diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index a7c68957a..000000000 --- a/.appveyor.yml +++ /dev/null @@ -1,65 +0,0 @@ -version: '{build}' - -# for Appveyor CI (windows) - -branches: - only: - - master - -os: Windows Server 2012 R2 - -clone_folder: c:\projects\STEPcode - -#grab zip instead of git clone -shallow_clone: true -platform: x64 -configuration: Debug - -# errors or couldn't be found by cmake -# - GENERATOR: "Visual Studio 9 2008" -# ARCH: 32 -# - GENERATOR: "Visual Studio 10" -# ARCH: 32 - -#no point in these without artifact support... -# - GENERATOR: "Visual Studio 11" - #ARCH: 32 - #- GENERATOR: "Visual Studio 12" - #ARCH: 32 - -environment: - matrix: - - GENERATOR: "Visual Studio 12 Win64" - ARCH: 64 - -# build: -# parallel: true -# project: ALL_BUILD.vcxproj - -#appveyor limits compile/test to 30 minutes -# to reduce time, only test schemas with files: ifc2x3, ap214e3, ap209 - -build_script: -- ps: | - cd c:\projects\STEPcode - mkdir build - cd build - cmake -version - grep --version - cmake .. -DSC_ENABLE_TESTING=ON -G"$env:GENERATOR" -DSC_BUILD_SCHEMAS="ifc2x3;ap214e3;ap209" - echo "filtering build output with grep" - cmake --build . --config Debug | grep -ve "CMake does not need to re-run because" -e "ZERO_CHECK.ZERO_CHECK" -e "^ Creating directory" - -#msbuld seems to provide no benefits, and I can't filter its output... -#msbuild SC.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /p:Configuration=Debug /p:Platform=x64 -# /toolsversion:14.0 /p:PlatformToolset=v140 - -test_script: - - cmd: echo Running CTest... - - cmd: cd c:\projects\STEPcode\build - - cmd: echo excluding test_inverse_attr3, which hangs - - cmd: ctest -j2 . -C Debug -E test_inverse_attr3 --output-on-failure - -# - cmd: grep -niB20 "Test Failed" Testing/Temporary/LastTest.log - -# we could upload a compiled zip somewhere (see Appveyor artifact documentation) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..626c5887b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,277 @@ +name: STEPCODE + +on: + workflow_dispatch: + pull_request: + +jobs: + windows: + name: Windows Latest MSVC + runs-on: windows-latest + strategy: + fail-fast: true + steps: + - name: Setup - CMake + uses: lukka/get-cmake@latest + + - name: Setup - Ninja + uses: seanmiddleditch/gha-setup-ninja@master + + - name: Checkout + uses: actions/checkout@v2 + + - name: Add github workspace to path + # https://github.community/t/deprecated-add-path/136621 + run: echo "$ENV{GITHUB_WORKSPACE}" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8 + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + + - name: Add cl.exe to PATH + uses: ilammy/msvc-dev-cmd@v1 + + - name: Configure + run: | + cmake -S . -B build -G Ninja -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_CXX_COMPILER="cl.exe" -DSC_ENABLE_TESTING=ON + # We do the following in order to help ensure files are "flushed" + # to disk before compilation is attempted + # https://superuser.com/a/1553374/1286142 + powershell Write-VolumeCache C + powershell Write-VolumeCache D + + - name: Build + run: cd build && ninja -j1 -v + + - name: Test + run: | + cd build && ctest -j1 . + + linux: + name: Ubuntu Latest GCC + runs-on: ubuntu-20.04 + strategy: + fail-fast: true + steps: + - name: Setup - CMake + uses: lukka/get-cmake@latest + + - name: Setup - Ninja + uses: seanmiddleditch/gha-setup-ninja@master + + # TODO - we will want this when the new parser work comes in, + # as we won't need perplex and the system tools should suffice + # to exercise the generator logic: + # + # - name: Setup - System + # env: + # DEBIAN_FRONTEND: noninteractive + # run: | + # sudo apt-get update + # # Install dev tools + # sudo apt-get install re2c lemon + # sudo apt-get clean + + - name: Checkout + uses: actions/checkout@v2 + + - name: Configure + run: | + export PATH=$ENV{GITHUB_WORKSPACE}:$PATH + cmake -S . -G Ninja -B build -D ENABLE_ALL=ON -D CMAKE_BUILD_TYPE=Release -DSC_ENABLE_TESTING=ON + + - name: Build + run: | + export PATH=$ENV{GITHUB_WORKSPACE}:$PATH + cmake --build build --config Release + + - name: Test + run: | + cd build && ctest -j1 . -C Release + + linux_clang: + name: Ubuntu Latest Clang + runs-on: ubuntu-20.04 + strategy: + fail-fast: true + steps: + - name: Setup - CMake + uses: lukka/get-cmake@latest + + - name: Setup - Ninja + uses: seanmiddleditch/gha-setup-ninja@master + + # TODO - we will want this when the new parser work comes in, + # as we won't need perplex and the system tools should suffice + # to exercise the generator logic: + # + # - name: Setup - System + # env: + # DEBIAN_FRONTEND: noninteractive + # run: | + # sudo apt-get update + # # Install dev tools + # sudo apt-get install re2c lemon + # sudo apt-get clean + + - name: Checkout + uses: actions/checkout@v2 + + - name: Configure + run: | + export PATH=$ENV{GITHUB_WORKSPACE}:$PATH + CC=clang CXX=clang++ cmake -S . -G Ninja -B build -D ENABLE_ALL=ON -D CMAKE_BUILD_TYPE=Release -DSC_ENABLE_TESTING=ON + + - name: Build + run: | + export PATH=$ENV{GITHUB_WORKSPACE}:$PATH + CC=clang CXX=clang++ cmake --build build --config Release + + - name: Test + run: | + cd build && ctest -j1 . -C Release + + + osx: + name: macOS Latest Clang + runs-on: macos-latest + strategy: + fail-fast: true + steps: + - name: Setup - CMake + uses: lukka/get-cmake@latest + + - name: Setup - Ninja + uses: seanmiddleditch/gha-setup-ninja@master + + - name: Checkout + uses: actions/checkout@v2 + + - name: Configure + run: | + export PATH=$ENV{GITHUB_WORKSPACE}:$PATH + export CC=clang + export CXX=clang++ + cmake -S . -G Ninja -B build -D CMAKE_BUILD_TYPE=Release -DSC_ENABLE_TESTING=ON + + - name: Build + run: | + export PATH=$ENV{GITHUB_WORKSPACE}:$PATH + cd build && ninja -j1 + + - name: Test + run: | + cd build && ctest -j1 . -C Release + + brlcad_linux: + name: BRL-CAD Linux step-g Test + runs-on: ubuntu-20.04 + strategy: + fail-fast: true + steps: + - name: Setup - CMake + uses: lukka/get-cmake@latest + + - name: Setup - Ninja + uses: seanmiddleditch/gha-setup-ninja@master + + - name: Setup - System + env: + DEBIAN_FRONTEND: noninteractive + run: | + sudo apt-get update + # Install dev tools + sudo apt-get install re2c lemon + sudo apt-get clean + + - name: Checkout + run: | + git clone --depth 1 https://github.com/BRL-CAD/brlcad.git -b main + cd brlcad/src/other/ext && rm -rf stepcode + git clone --depth 1 https://github.com/stepcode/stepcode.git -b develop + # Ordinarily BRL-CAD keeps track of what files are supposed to be + # present in the repository. In this case we're not interested in + # updating the list to the working stepcode filelist, so use an empty + # list instead + echo "set(stepcode_ignore_files)" > stepcode.dist + cd ../../../../ + + + - name: Configure + run: | + export PATH=$ENV{GITHUB_WORKSPACE}:$PATH + cd brlcad + cmake -S . -G Ninja -B build -DENABLE_ALL=ON -DCMAKE_BUILD_TYPE=Release -DEXT_BUILD_VERBOSE=ON + cd .. + + - name: Build + run: | + export PATH=$ENV{GITHUB_WORKSPACE}:$PATH + cd brlcad + cmake --build build --config Release --target step-g + cd .. + + - name: Test + run: | + export PATH=$ENV{GITHUB_WORKSPACE}:$PATH + cd brlcad/build + ./bin/step-g ../db/nist/NIST_MBE_PMI_3.stp -o nist3.g + cd ../.. + + + brlcad_windows: + name: BRL-CAD Windows step-g Test + runs-on: windows-latest + strategy: + fail-fast: true + steps: + - name: Setup - CMake + uses: lukka/get-cmake@latest + + - name: Setup - Ninja + uses: seanmiddleditch/gha-setup-ninja@master + + - name: Add github workspace to path + # https://github.community/t/deprecated-add-path/136621 + run: echo "$ENV{GITHUB_WORKSPACE}" | Out-File -Append -FilePath $env:GITHUB_PATH -Encoding utf8 + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + + - name: Add cl.exe to PATH + uses: ilammy/msvc-dev-cmd@v1 + + - name: Checkout + run: | + git clone --depth 1 https://github.com/BRL-CAD/brlcad.git -b main + cd brlcad/src/other/ext + cmake -E rm -r stepcode + git clone --depth 1 https://github.com/stepcode/stepcode.git -b develop + # Ordinarily BRL-CAD keeps track of what files are supposed to be + # present in the repository. In this case we're not interested in + # updating the list to the working stepcode filelist, so use an empty + # list instead + echo "set(stepcode_ignore_files)" > stepcode.dist + cd ../../../../ + + - name: Configure + run: | + cd brlcad && cmake -S . -B build -G Ninja -DCMAKE_C_COMPILER="cl.exe" -DCMAKE_CXX_COMPILER="cl.exe" -DSC_ENABLE_TESTING=ON + cd .. + # We do the following in order to help ensure files are "flushed" + # to disk before compilation is attempted + # https://superuser.com/a/1553374/1286142 + powershell Write-VolumeCache C + powershell Write-VolumeCache D + + - name: Build + run: | + cd brlcad/build + ninja -j1 -v step-g + cd ../.. + + - name: Test + run: | + cd brlcad/build + ./bin/step-g.exe ../db/nist/NIST_MBE_PMI_3.stp -o nist3.g + cd ../.. + diff --git a/.gitignore b/.gitignore index 008fe8f32..c39a631c2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,21 @@ +# Common build directories used in the source tree /build +/.build + +# Temporary files +*~ +\#*\# +.\#* +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-v][a-z] +[._]sw[a-p] +**/__pycache__/ + +# OS specific files +.DS_Store +.DS_Store? + +# Tool specific patterns *.kdev4 .kdev_include_paths diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5d186c6b2..000000000 --- a/.travis.yml +++ /dev/null @@ -1,19 +0,0 @@ -sudo: false -language: cpp -compiler: - - clang -script: mkdir build && cd build && cmake .. -DSC_ENABLE_TESTING=ON && make -j3 && ctest -j2 --output-on-failure -branches: - only: - - master -notifications: - irc: "chat.freenode.net#stepcode" - email: scl-dev@groups.google.com - on_success: change - on_failure: always -os: - - linux - - osx -matrix: - allow_failures: - - os: osx diff --git a/AUTHORS b/AUTHORS index 0e6c2518a..998c16349 100644 --- a/AUTHORS +++ b/AUTHORS @@ -19,6 +19,7 @@ Paviot, Thomas (tpaviot) Pictor, Mark (mpictor) Reed, Nick (nickreed) Shah, Kesha (kesha, keshashah) +Sparks, Devon (devonsparks) Thomas, Dawn (homovulgaris, madant) Wouters, Dave (davyw) Yapp, Clifford (starseeker) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7708df8e8..4d61fd650 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,60 +40,131 @@ project(SC) +# Minimum required version of CMake +cmake_minimum_required(VERSION 3.12) +if (POLICY CMP0077) + cmake_policy(SET CMP0077 OLD) +endif (POLICY CMP0077) + # SC version 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) - -# Minimum required version of CMake -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) +set(SC_VERSION_MINOR 8) +set(SC_VERSION_PATCH 1) +set(SC_VERSION ${SC_VERSION_MAJOR}.${SC_VERSION_MINOR}.${SC_VERSION_PATCH}) + +# Set language standards +set(CMAKE_C_EXTENSIONS OFF) +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) # 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") -if(NOT SC_IS_SUBBUILD) - set(CMAKE_MODULE_PATH "${SC_CMAKE_DIR};${CMAKE_MODULE_PATH}") -else(NOT SC_IS_SUBBUILD) - set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${SC_CMAKE_DIR}") -endif(NOT SC_IS_SUBBUILD) +list(APPEND CMAKE_MODULE_PATH "${SC_CMAKE_DIR}") + +# OpenBSD has its own naming conventions. Set a platform variable based on +# the OS name so we can test for it succinctly. +if ("${CMAKE_SYSTEM}" MATCHES ".*OpenBSD.*") + set(OPENBSD ON) +endif ("${CMAKE_SYSTEM}" MATCHES ".*OpenBSD.*") + +#--------------------------------------------------------------------- +# Set up various relative path variables and build output directories +include(Path_Setup) + +#--------------------------------------------------------------------- +# 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 +if(NOT DEFINED CMAKE_SKIP_BUILD_RPATH) + set(CMAKE_SKIP_BUILD_RPATH FALSE) +endif() + +# when building, don't use the install RPATH already +# (but later on when installing) +if(NOT DEFINED CMAKE_BUILD_WITH_INSTALL_RPATH) + set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) +endif() + +# the RPATH/INSTALL_NAME_DIR to be used when installing +if (NOT APPLE) + if(NOT DEFINED CMAKE_INSTALL_RPATH) + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:\$ORIGIN/../lib") + endif() +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 +if(NOT DEFINED CMAKE_INSTALL_NAME_DIR) + set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib") +endif() + +# add the automatically determined parts of the RPATH which point to +# directories outside the build tree to the install RPATH +if(NOT DEFINED CMAKE_INSTALL_RPATH_USE_LINK_PATH) + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +endif() + -# testing and compilation options, build output dirs, install dirs, uninstall, package creation, etc -include(${SC_CMAKE_DIR}/SC_Build_opts.cmake) +#--------------------------------------------------------------------- +# Build options +option(BUILD_SHARED_LIBS "Build shared libraries" ON) +option(BUILD_STATIC_LIBS "Build static libraries" OFF) + +option(SC_PYTHON_GENERATOR "Compile exp2python" ON) +option(SC_CPP_GENERATOR "Compile exp2cxx" ON) + +option(SC_TRACE_FPRINTF "Enable extra comments in generated code so the code's source in exp2cxx may be located" OFF) + +option(SC_ENABLE_COVERAGE "Enable code coverage test" OFF) +if (SC_ENABLE_COVERAGE AND ${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + set(CMAKE_C_FLAGS_DEBUG "-O0 -g -fprofile-arcs -ftest-coverage" CACHE STRING "Extra compile flags required by code coverage" FORCE) + set(CMAKE_CXX_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) +endif (SC_ENABLE_COVERAGE AND ${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + +option(SC_BUILD_EXPRESS_ONLY "Only build express parser." OFF) +mark_as_advanced(SC_BUILD_EXPRESS_ONLY) + +option(SC_ENABLE_TESTING "Enable unittesting framework" OFF) +if(SC_ENABLE_TESTING) + if(NOT "${SC_BUILD_EXPRESS_ONLY}" AND NOT DEFINED SC_BUILD_SCHEMAS) + set(SC_BUILD_SCHEMAS "ALL") #test all schemas, unless otherwise specified + endif() + include(CTest) +endif(SC_ENABLE_TESTING) # SC_ADDEXEC and SC_ADDLIB macros, dllimport/export, etc -include(${SC_CMAKE_DIR}/SC_Targets.cmake) +include(SC_Targets) # Macros related to paths -include(${SC_CMAKE_DIR}/SC_Paths.cmake) +include(SC_Paths) # locale stuff -include(${SC_CMAKE_DIR}/SC_Locale.cmake) +include(SC_Locale) # logic related to regenerating the lexer and parser source code -include(${SC_CMAKE_DIR}/SC_Regenerate.cmake) +include(SC_Regenerate) + +# create config.h header +include(SC_Config_Headers) 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) +if(NOT "${SC_BUILD_EXPRESS_ONLY}" AND 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) + "** Note: CMake variable SC_BUILD_SCHEMAS was not set - defaults to building ALL 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() if(NOT SC_IS_SUBBUILD) list(APPEND CONFIG_END_MESSAGES @@ -102,23 +173,14 @@ if(NOT SC_IS_SUBBUILD) ".. Generating step can take a while if you are building several schemas.") endif(NOT SC_IS_SUBBUILD) -# create config headers sc_cf.h and sc_version_string.h -include(${SC_CMAKE_DIR}/SC_Config_Headers.cmake) - - ################ 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() +endif() +if (${CMAKE_C_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_C_COMPILER_ID} STREQUAL "Clang") add_definitions(-pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long) - if(HAVE_NULLPTR) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") - endif(HAVE_NULLPTR) endif() include_directories( @@ -126,7 +188,6 @@ include_directories( ${SC_BINARY_DIR}/include ) -add_subdirectory(src/base) add_subdirectory(src/express) add_subdirectory(src/exppp) add_subdirectory(src/exp2cxx) @@ -143,9 +204,19 @@ if(SC_ENABLE_TESTING) 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(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 ") + include(CPack) +endif(NOT SC_IS_SUBBUILD) + # 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. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b8d1f443e..62e9503db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,9 +11,12 @@ We love contributions! * Encouraged but not enforced: each commit should stand alone, in the sense that the code should compile and run at that point. * One major topic per pull request. Commits that fix small things (typos, formatting) are perfectly acceptable in a PR fixing a bug or adding a feature. * Tests are good. Tests are required unless you're fixing something simple or that was obviously broken. + * Do not change EXPRESS schema definition without reference to an upstream change. * Make your changes and push them to your GitHub repo * Once your branch is pushed, submit a pull request. -* We'll look at the PR and either merge or add feedback. If there isn't any activity within several days, send a message to the mailing list - `scl-dev` AT `groups.google.com`. + - enable github option on each PR 'Allow edits from maintainers', refer to github help if necessary +* We'll look at the PR and either merge (possibly after rebase) or add feedback. + - If there isn't any activity within several days send a message to the mailing list - `scl-dev` AT `groups.google.com`. ## Coding Standards diff --git a/COPYING b/COPYING index 27cd65330..48d3fd176 100644 --- a/COPYING +++ b/COPYING @@ -1,108 +1,47 @@ -Modifications to the original NIST code are (C)opyright by their -respective authors. Unless otherwise specified, they are copyright -on the date those changes were committed to whichever repository -they were committed to first (i.e. BRL-CAD on SourceForge.net, -mpictor/StepClassLibrary or stepcode/stepcode on github). +STEPcode is provided as a collective work under the 3-clause BSD +license. As some portions are not subject to copyright in some +jurisdictions, see INTENT.md for additional details regarding intent +and history. See the AUTHORS file for a list of contributors and +copyright holders. -Modifications which were first commited to the repository on github -are licensed under the 3-clause BSD license below. Changes committed -to BRL-CAD either contain license information mentioning BRL-CAD -near the top of the file, or are licensed under the same terms that -NIST used. +Code generated by STEPcode containing substantial parts of STEPcode +complex enough to have copyright protection are subject to the terms +of this license. -******************************************************************** -3-clause BSD license: - -Copyright (c) , -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. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -******************************************************************** +STEPcode acknowledgement and/or attribution is appreciated regardless +of license or copyright status. ******************************************************************** - ORIGINAL NIST TEXT FOLLOWS + 3-Clause BSD License ******************************************************************** -This software was produced by the National Institute of Standards and -Technology (NIST), an agency of the U.S. government, and by statute is -not subject to copyright in the United States. Recipients of this -software assume all responsibility associated with its operation, -modification, maintenance, and subsequent redistribution. - -Acknowledgements: -The STEP Class Library (SCL) was developed by the Manufacturing -Systems Integration Division at NIST to support testing of the -Standard for the Exchange of Product Model Data (a.k.a STEP) and -validation of STEP's emerging implementation specifications. Funding -for the project has come from the Department of Commerce and the -Department of Defense agencies including the Office of the Defense -CALS (Continuous Acquisition and Life-Cycle Support) Executive and -the Defense Advanced Research Projects Agency (DARPA). Recent -enhancements were sponsored by the National Information Infrastructure -Protocols Consortium and NIST's Systems Integration for Manufacturing -Applications (SIMA) program. - - -/* ******************************************************************** - * D I S C L A I M E R - * (February 6, 1992) - * - * There is no warranty for the NIST PDES Toolkit. - * If the NIST PDES Toolkit - * is modified by someone else and passed on, NIST wants - * the Toolkit's recipients to know that what they have is not what NIST - * distributed. - * - * Policies - * - * 1. Anyone may copy and distribute verbatim copies of the NIST PDES Toolkit - * source code as received in any medium. - * - * 2. Anyone may modify your copy or copies of the NIST PDES Toolkit source - * code or any portion of it, and copy and distribute such modifications - * provided that all modifications are clearly associated with the entity - * that performs the modifications. - * - * NO WARRANTY - * =========== - * - * NIST PROVIDES ABSOLUTELY NO WARRANTY. THE NIST PDES TOOLKIT - * IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS - * WITH YOU. SHOULD ANY PORTION OF THE NIST PDES TOOLKIT PROVE DEFECTIVE, - * YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - * - * IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES, - * INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, - * INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR - * INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA - * BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A - * FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY - * NIST) THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. - */ - +Copyright (c) 2009-2019 STEPcode AUTHORS +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +1. Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +2. 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. + +3. Neither the name of the copyright holder nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/INTENT.md b/INTENT.md new file mode 100644 index 000000000..06d306e6a --- /dev/null +++ b/INTENT.md @@ -0,0 +1,102 @@ +## Licensing Intent + +The intent is that this software and documentation ("Project") should +be treated as if it is licensed under the license(s) associated with +the Project ("License") in the `COPYING` file. However, because some +contributors work for the United States (U.S.) Federal Government, it +is not that simple. + +The portions of this Project written by United States (U.S.) federal +government employees within the scope of their federal employment are +ineligible for copyright protection in the U.S.; this is generally +understood to mean that these portions of the Project are placed in +the public domain. + +In countries where copyright protection is available (which does not +include the U.S.), contributions made by U.S. Federal government +employees are released under the License. Merged contributions from +private contributors are released under the License. + +## Background History + +STEPcode was originally developed as the STEP Class Libraries (SCL) by +the U.S. National Institute of Standards and Technology (NIST). Prior +to 2009, the U.S. Army Research Laboratory and members of the BRL-CAD +open source community researched freely available open source options +for ISO 10303 STEP support. Development had ceased, no open source +community existed, the code was out of date in many regards, and +additional work was needed to become production-ready, but SCL was +found to be a usable reference implementation. + +Consulting with NIST and others circa 2009, the BRL-CAD community +began efforts to take over SCL development, modernization, and code +enhancements. The BRL-CAD community purchased licenses for the ISO +10303 standard and began working to bring SCL up-to-date with the +latest specification. By 2011, significant progress had been made, +the project had garnered attention from others, and STEPcode was +establishd as an independent project. + +## Original NIST License Text + +This software was [originally] produced by the National Institute of +Standards and Technology (NIST), an agency of the U.S. government, and +by statute is not subject to copyright in the United +States. Recipients of this software assume all responsibility +associated with its operation, modification, maintenance, and +subsequent redistribution. + +Acknowledgements: +The STEP Class Library (SCL) was developed by the Manufacturing +Systems Integration Division at NIST to support testing of the +Standard for the Exchange of Product Model Data (a.k.a STEP) and +validation of STEP's emerging implementation specifications. Funding +for the project has come from the Department of Commerce and the +Department of Defense agencies including the Office of the Defense +CALS (Continuous Acquisition and Life-Cycle Support) Executive and +the Defense Advanced Research Projects Agency (DARPA). Recent +enhancements [circa 1992] were sponsored by the National Information Infrastructure +Protocols Consortium and NIST's Systems Integration for Manufacturing +Applications (SIMA) program. + +~~~~ +/* ******************************************************************** + * D I S C L A I M E R + * (February 6, 1992) + * + * There is no warranty for the NIST PDES Toolkit. + * If the NIST PDES Toolkit + * is modified by someone else and passed on, NIST wants + * the Toolkit's recipients to know that what they have is not what NIST + * distributed. + * + * Policies + * + * 1. Anyone may copy and distribute verbatim copies of the NIST PDES Toolkit + * source code as received in any medium. + * + * 2. Anyone may modify your copy or copies of the NIST PDES Toolkit source + * code or any portion of it, and copy and distribute such modifications + * provided that all modifications are clearly associated with the entity + * that performs the modifications. + * + * NO WARRANTY + * =========== + * + * NIST PROVIDES ABSOLUTELY NO WARRANTY. THE NIST PDES TOOLKIT + * IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS + * WITH YOU. SHOULD ANY PORTION OF THE NIST PDES TOOLKIT PROVE DEFECTIVE, + * YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + * + * IN NO EVENT WILL NIST BE LIABLE FOR DAMAGES, + * INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL, + * INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR + * INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA + * BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A + * FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY + * NIST) THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. + */ + ~~~~ \ No newline at end of file diff --git a/NEWS b/NEWS index bdf02e439..564f1e155 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,8 @@ -STEPcode -- http://github.com/stepcode/stepcode -- http://stepcode.org ************************************************************************ + STEPcode + http://github.com/stepcode/stepcode +************************************************************************ + Release 0.8 (December, 2014) New since v0.7: @@ -176,7 +179,7 @@ There were also some issues with the configure script and some makefiles which are addressed, as well as a new macro that is at least required for gcc. -Remaing problem: The p21 file scanner of SCL currently +Remaining problem: The p21 file scanner of SCL currently does not allow for comments within the parameter list of data records. Only comments outside of data records are accepted. @@ -252,7 +255,7 @@ the TD for label. - Fixed the casting operator for the class representing EXPRESS enumeration types. It was returning the last element of the enum type -as the the default when the enum was unset. This choice predated enums +as the default when the enum was unset. This choice predated enums having an unset enum value. It now returns _unset as the default when the enum is unset. @@ -794,7 +797,7 @@ When this case of multiple inheritance is encountered attributes are duplicated. This case of multiple inheritance may possibly be avoided by modifying the EXPRESS schema by breaking some links in the inheritance hierarchy. This will not have an adverse affect on the -implemementation. The user may choose to use the current or previous +implementation. The user may choose to use the current or previous method of handling multiple inheritance. The current method is the default behavior. The previous method is obtained by supplying the -s (or -S) option with the exp2cxx code generator or the mkProbe @@ -987,7 +990,7 @@ the attribute value field in the entity editor. If there wasn't a value in the attribute previously, then the field will contain just the type specifier, e.g., Str1() if Str1 is the type selected. -If a value exists in the field, it is modified to accomodate the new +If a value exists in the field, it is modified to accommodate the new specifier. This means the following: o If the value in the field starts with a single-quote ('), it is assumed to be a string literal, and is completely wrapped in the new diff --git a/README.md b/README.md index 4df78fd0d..502388cf7 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,7 @@ - Travis-CI | AppVeyor CI -:-------------:|:---------------: -Linux, OSX (LLVM) | Windows (MSVC) -[![Build Status](https://travis-ci.org/stepcode/stepcode.svg?branch=master)](https://travis-ci.org/stepcode/stepcode) | [![Build status](https://ci.appveyor.com/api/projects/status/3fbr9t9gfa812oqu?svg=true)](https://ci.appveyor.com/project/mpictor/stepcode) +![Build Status](https://github.com/stepcode/stepcode/actions/workflows/build.yml/badge.svg?branch=develop) *********************************************************************** -STEPcode v0.8 -- stepcode.org, github.com/stepcode/stepcode +STEPcode v0.8 -- github.com/stepcode/stepcode * What is STEPcode? SC reads ISO10303-11 EXPRESS schemas and generates C++ source code that can read and write Part 21 files conforming diff --git a/SC_VERSION.txt b/SC_VERSION.txt deleted file mode 100644 index aec258df7..000000000 --- a/SC_VERSION.txt +++ /dev/null @@ -1 +0,0 @@ -0.8 diff --git a/cmake/FindLEMON.cmake b/cmake/FindLEMON.cmake index 19aa0d500..83c63c487 100644 --- a/cmake/FindLEMON.cmake +++ b/cmake/FindLEMON.cmake @@ -47,158 +47,136 @@ find_program(LEMON_EXECUTABLE lemon DOC "path to the lemon executable") mark_as_advanced(LEMON_EXECUTABLE) -if (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) - # look for the template in share - if (DATA_DIR AND EXISTS "${DATA_DIR}/lemon/lempar.c") - set (LEMON_TEMPLATE "${DATA_DIR}/lemon/lempar.c") - elseif (EXISTS "share/lemon/lempar.c") - set (LEMON_TEMPLATE "share/lemon/lempar.c") - elseif (EXISTS "/usr/share/lemon/lempar.c") - set (LEMON_TEMPLATE "/usr/share/lemon/lempar.c") - endif (DATA_DIR AND EXISTS "${DATA_DIR}/lemon/lempar.c") -endif (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) - -if (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) - # look for the template in bin dir - get_filename_component(lemon_path ${LEMON_EXECUTABLE} PATH) - if (lemon_path) - if (EXISTS ${lemon_path}/lempar.c) - set (LEMON_TEMPLATE "${lemon_path}/lempar.c") - endif (EXISTS ${lemon_path}/lempar.c) - if (EXISTS /usr/share/lemon/lempar.c) - set (LEMON_TEMPLATE "/usr/share/lemon/lempar.c") - endif (EXISTS /usr/share/lemon/lempar.c) - endif (lemon_path) -endif(LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) - -if (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) - # fallback - set (LEMON_TEMPLATE "lempar.c") - if (NOT EXISTS ${LEMON_TEMPLATE}) - message(WARNING "Lemon's lempar.c template file could not be found automatically, set LEMON_TEMPLATE") - endif (NOT EXISTS ${LEMON_TEMPLATE}) -endif (LEMON_EXECUTABLE AND NOT LEMON_TEMPLATE) - -mark_as_advanced(LEMON_TEMPLATE) +if (LEMON_EXECUTABLE) + if(NOT LEMON_TEMPLATE) + # look for the template, if we've not already been told where it is + if (DATA_DIR AND EXISTS "${DATA_DIR}/lemon/lempar.c") + find_file(LEMON_TEMPLATE lempar.c + PATHS "${DATA_DIR}/lemon/lempar.c" + NO_DEFAULT_PATH) + endif () + + # If the above did not succeed, check standard locations + get_filename_component(lemon_dir ${LEMON_EXECUTABLE} DIRECTORY) + find_file(LEMON_TEMPLATE lempar.c + PATHS "${lemon_dir}" "/usr/share/lemon" + NO_DEFAULT_PATH) + mark_as_advanced(LEMON_TEMPLATE) + endif() + + # We need a template to be able to use lemon correctly + if(NOT LEMON_TEMPLATE) + message(FATAL_ERROR "Failed to find lemon template file (lempar.c) - need to set LEMON_TEMPLATE") + endif() + + # Define the function + # LEMON_TARGET( + # []) + # which will create a custom rule to generate a parser. is + # the path to a lemon file. is the desired name for the + # generated source file. is the desired name for the + # generated header which contains the token list. Anything in the optional + # parameter is appended to the lemon command line. + # + # ==================================================================== + # Example: + # + # find_package(LEMON) + # LEMON_TARGET(MyParser parser.y parser.c parser.h) + # add_executable(Foo main.cpp ${LEMON_MyParser_OUTPUTS}) + # ==================================================================== + + include(CMakeParseArguments) + + if(NOT COMMAND LEMON_TARGET) + function(LEMON_TARGET Name LemonInput LemonOutput) + set(LT_ARGS DEFINES_FILE COMPILE_FLAGS) + cmake_parse_arguments(LEMON_TARGET_ARG "" "${LT_ARGS}" "" ${ARGN}) + + if(NOT "${LEMON_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "") + set(LEMON_EXECUTABLE_opts "${LEMON_TARGET_ARG_COMPILE_FLAGS}") + separate_arguments(LEMON_EXECUTABLE_opts) + else() + set(LEMON_EXECUTABLE_opts "") + endif() + + # check for LemonOutput + get_filename_component(_basename ${LemonOutput} NAME_WE) + get_filename_component(_out_src_file ${LemonOutput} NAME) + get_filename_component(_out_dir ${LemonOutput} PATH) + if(NOT "${_out_dir}" STREQUAL "") + message(WARNING "Full path specified for LemonOutput - should be filename only") + endif() + + # set report file + set(_out_rpt_file "${_basename}.out") + + # check for DEFINES_FILE + if ("${LEMON_TARGET_ARG_DEFINES_FILE}" STREQUAL "") + set(_out_hdr_file "${_basename}.h") + else() + get_filename_component(_out_dir ${LEMON_TARGET_ARG_DEFINES_FILE} PATH) + get_filename_component(_out_hdr_file ${LEMON_TARGET_ARG_DEFINES_FILE} NAME) + if(NOT "${_out_dir}" STREQUAL "") + message(WARNING "Full path specified for DEFINES_FILE - should be filename only") + endif() + endif() + + # input file + get_filename_component(_in_y_path ${LemonInput} ABSOLUTE) + get_filename_component(_in_y_file ${LemonInput} NAME) + + # Stage the source file in the binary directory for lemon. We need to make + # sure it's fully copied, so use a sentinel guard + add_custom_command( + OUTPUT ${_in_y_file} + COMMAND ${CMAKE_COMMAND} -E copy ${_in_y_path} ${CMAKE_CURRENT_BINARY_DIR} + ) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_in_y_file}.sentinel + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/${_in_y_file}.sentinel + DEPENDS ${_in_y_file} + ) + add_custom_target(${Name}_input_cpy DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${_in_y_file}.sentinel) -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LEMON DEFAULT_MSG LEMON_EXECUTABLE LEMON_TEMPLATE) - -# Define the macro -# LEMON_TARGET( -# []) -# which will create a custom rule to generate a parser. is -# the path to a lemon file. is the desired name for the -# generated source file. is the desired name for the -# generated header which contains the token list. Anything in the optional -# parameter is appended to the lemon command line. -# -# ==================================================================== -# Example: -# -# find_package(LEMON) -# LEMON_TARGET(MyParser parser.y parser.c parser.h) -# add_executable(Foo main.cpp ${LEMON_MyParser_OUTPUTS}) -# ==================================================================== - -include(CMakeParseArguments) - -if(NOT COMMAND LEMON_TARGET) - macro(LEMON_TARGET Name Input) - - get_filename_component(IN_FILE_WE ${Input} NAME_WE) - set(LVAR_PREFIX ${Name}_${IN_FILE_WE}) - - if(${ARGC} GREATER 3) - CMAKE_PARSE_ARGUMENTS(${LVAR_PREFIX} "" "OUT_SRC_FILE;OUT_HDR_FILE;WORKING_DIR;EXTRA_ARGS" "" ${ARGN}) - endif(${ARGC} GREATER 3) - - # Need a working directory - if("${${LVAR_PREFIX}_WORKING_DIR}" STREQUAL "") - set(${LVAR_PREFIX}_WORKING_DIR "${CMAKE_CURRENT_BINARY_DIR}/${LVAR_PREFIX}") - endif("${${LVAR_PREFIX}_WORKING_DIR}" STREQUAL "") - file(MAKE_DIRECTORY ${${LVAR_PREFIX}_WORKING_DIR}) - - # Output source file - if ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "") - set(${LVAR_PREFIX}_OUT_SRC_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.c) - else ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "") - get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_SRC_FILE} PATH) - if(NOT "${specified_out_dir}" STREQUAL "") - message(FATAL_ERROR "\nFull path specified for OUT_SRC_FILE - should be filename only.\n") - endif(NOT "${specified_out_dir}" STREQUAL "") - set(${LVAR_PREFIX}_OUT_SRC_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${${LVAR_PREFIX}_OUT_SRC_FILE}) - endif ("${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "") - - # Output header file - if ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "") - set(${LVAR_PREFIX}_OUT_HDR_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.h) - else ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "") - get_filename_component(specified_out_dir ${${LVAR_PREFIX}_OUT_HDR_FILE} PATH) - if(NOT "${specified_out_dir}" STREQUAL "") - message(FATAL_ERROR "\nFull path specified for OUT_HDR_FILE - should be filename only.\n") - endif(NOT "${specified_out_dir}" STREQUAL "") - set(${LVAR_PREFIX}_OUT_HDR_FILE ${${LVAR_PREFIX}_WORKING_DIR}/${${LVAR_PREFIX}_OUT_HDR_FILE}) - endif ("${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "") - - # input file - get_filename_component(in_full ${Input} ABSOLUTE) - if("${in_full}" STREQUAL "${Input}") - set(lemon_in_file ${Input}) - else("${in_full}" STREQUAL "${Input}") - set(lemon_in_file "${CMAKE_CURRENT_SOURCE_DIR}/${Input}") - endif("${in_full}" STREQUAL "${Input}") - - - # names of lemon output files will be based on the name of the input file - set(LEMON_GEN_SOURCE ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.c) - set(LEMON_GEN_HEADER ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.h) - set(LEMON_GEN_OUT ${${LVAR_PREFIX}_WORKING_DIR}/${IN_FILE_WE}.out) - - # copy input to bin directory and run lemon - get_filename_component(INPUT_NAME ${Input} NAME) - add_custom_command( - OUTPUT ${LEMON_GEN_OUT} ${LEMON_GEN_SOURCE} ${LEMON_GEN_HEADER} - COMMAND ${CMAKE_COMMAND} -E copy ${lemon_in_file} ${${LVAR_PREFIX}_WORKING_DIR}/${INPUT_NAME} - COMMAND ${LEMON_EXECUTABLE} -T${LEMON_TEMPLATE} ${${LVAR_PREFIX}_WORKING_DIR}/${INPUT_NAME} ${${LVAR_PREFIX}__EXTRA_ARGS} - DEPENDS ${Input} ${LEMON_TEMPLATE} ${LEMON_EXECUTABLE_TARGET} - WORKING_DIRECTORY ${${LVAR_PREFIX}_WORKING_DIR} - COMMENT "[LEMON][${Name}] Building parser with ${LEMON_EXECUTABLE}" - ) - - # rename generated outputs - if(NOT "${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "${LEMON_GEN_SOURCE}") + # execute lemon add_custom_command( - OUTPUT ${${LVAR_PREFIX}_OUT_SRC_FILE} - COMMAND ${CMAKE_COMMAND} -E copy ${LEMON_GEN_SOURCE} ${${LVAR_PREFIX}_OUT_SRC_FILE} - DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_SOURCE} + OUTPUT ${_out_src_file} ${_basename}.h + COMMAND ${LEMON_EXECUTABLE} -T${LEMON_TEMPLATE} ${LEMON_EXECUTABLE_opts} ${_in_y_file} + DEPENDS ${Name}_input_cpy + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "[LEMON][${Name}] Building parser with ${LEMON_EXECUTABLE}" ) - set(LEMON_${Name}_OUTPUTS ${${LVAR_PREFIX}_OUT_SRC_FILE} ${LEMON_${Name}_OUTPUTS}) - endif(NOT "${${LVAR_PREFIX}_OUT_SRC_FILE}" STREQUAL "${LEMON_GEN_SOURCE}") - if(NOT "${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "${LEMON_GEN_HEADER}") + + # rename the header add_custom_command( - OUTPUT ${${LVAR_PREFIX}_OUT_HDR_FILE} - COMMAND ${CMAKE_COMMAND} -E copy ${LEMON_GEN_HEADER} ${${LVAR_PREFIX}_OUT_HDR_FILE} - DEPENDS ${LemonInput} ${LEMON_EXECUTABLE_TARGET} ${LEMON_GEN_HEADER} + OUTPUT ${_out_hdr_file} + COMMAND ${CMAKE_COMMAND} ARGS -E rename ${_basename}.h ${_out_hdr_file} + DEPENDS ${_out_src_file} ${_basename}.h + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} ) - set(LEMON_${Name}_OUTPUTS ${${LVAR_PREFIX}_OUT_HDR_FILE} ${LEMON_${Name}_OUTPUTS}) - endif(NOT "${${LVAR_PREFIX}_OUT_HDR_FILE}" STREQUAL "${LEMON_GEN_HEADER}") - set(LEMON_${Name}_OUTPUTS ${LEMON_${Name}_OUTPUTS} ${LEMON_GEN_OUT}) + # set the return values + # TODO: for generated sources even headers should be target dependencies + set(LEMON_${Name}_DEFINED TRUE PARENT_SCOPE) + set(LEMON_${Name}_OUTPUT_HEADER "${CMAKE_CURRENT_BINARY_DIR}/${_out_hdr_file}" PARENT_SCOPE) + set(LEMON_${Name}_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE) + set(LEMON_${Name}_OUTPUTS "${_out_src_file}" PARENT_SCOPE) - # make sure we clean up generated output and copied input - set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${LEMON_${Name}_OUTPUTS}") - set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${${LVAR_PREFIX}_WORKING_DIR}/${INPUT_NAME}") + # TODO - remove once perplex goes away... + add_custom_target(${Name} DEPENDS ${_out_hdr_file}) - # macro ran successfully - set(LEMON_${Name}_DEFINED TRUE) + # make sure we clean up generated output and copied input + set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${_out_src_file}") + set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${CMAKE_CURRENT_BINARY_DIR}/${_in_y_file}") - set(LEMON_${Name}_SRC ${${LVAR_PREFIX}_OUT_SRC_FILE}) - set(LEMON_${Name}_HDR ${${LVAR_PREFIX}_OUT_HDR_FILE}) - set(LEMON_${Name}_INCLUDE_DIR ${${LVAR_PREFIX}_WORKING_DIR}) + endfunction(LEMON_TARGET) + endif(NOT COMMAND LEMON_TARGET) - endmacro(LEMON_TARGET) -endif(NOT COMMAND LEMON_TARGET) +endif(LEMON_EXECUTABLE) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LEMON REQUIRED_VARS LEMON_EXECUTABLE LEMON_TEMPLATE) #============================================================ # FindLEMON.cmake ends here diff --git a/cmake/FindPERPLEX.cmake b/cmake/FindPERPLEX.cmake index 22d632032..022a07666 100644 --- a/cmake/FindPERPLEX.cmake +++ b/cmake/FindPERPLEX.cmake @@ -227,6 +227,14 @@ if(NOT COMMAND PERPLEX_TARGET) set(PERPLEX_${Name}_SRC ${${PVAR_PREFIX}_OUT_SRC_FILE}) set(PERPLEX_${Name}_HDR ${${PVAR_PREFIX}_OUT_HDR_FILE}) set(PERPLEX_${Name}_INCLUDE_DIR ${${PVAR_PREFIX}_WORKING_DIR}) + + add_custom_command( + OUTPUT ${${PVAR_PREFIX}_WORKING_DIR}/${Name}.sentinel + COMMAND ${CMAKE_COMMAND} -E touch ${${PVAR_PREFIX}_WORKING_DIR}/${Name}.sentinel + DEPENDS ${${PVAR_PREFIX}_OUT_SRC_FILE} ${${PVAR_PREFIX}_OUT_HDR_FILE} + ) + add_custom_target(${Name} DEPENDS ${${PVAR_PREFIX}_WORKING_DIR}/${Name}.sentinel) + endmacro(PERPLEX_TARGET) endif(NOT COMMAND PERPLEX_TARGET) @@ -240,12 +248,12 @@ if(NOT COMMAND ADD_PERPLEX_LEMON_DEPENDENCY) message(SEND_ERROR "PERPLEX target `${PERPLEXTarget}' does not exists.") endif() - if(NOT LEMON_${LemonTarget}_HDR) + if(NOT TARGET ${LemonTarget}) message(SEND_ERROR "Lemon target `${LemonTarget}' does not exists.") endif() set_source_files_properties(${PERPLEX_${PERPLEXTarget}_SRC} - PROPERTIES OBJECT_DEPENDS ${LEMON_${LemonTarget}_HDR}) + PROPERTIES OBJECT_DEPENDS ${LEMON_${LemonTarget}_OUTPUT_HEADER}) endmacro(ADD_PERPLEX_LEMON_DEPENDENCY) endif(NOT COMMAND ADD_PERPLEX_LEMON_DEPENDENCY) diff --git a/cmake/FindRE2C.cmake b/cmake/FindRE2C.cmake index 5450c34a9..cab426eef 100644 --- a/cmake/FindRE2C.cmake +++ b/cmake/FindRE2C.cmake @@ -6,134 +6,163 @@ find_program(RE2C_EXECUTABLE re2c DOC "path to the re2c executable") mark_as_advanced(RE2C_EXECUTABLE) -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(RE2C DEFAULT_MSG RE2C_EXECUTABLE) +if(RE2C_EXECUTABLE) -# Provide a macro to generate custom build rules: + execute_process(COMMAND ${RE2C_EXECUTABLE} -v + OUTPUT_VARIABLE RE2C_version_output + ERROR_VARIABLE RE2C_version_error + RESULT_VARIABLE RE2C_version_result + OUTPUT_STRIP_TRAILING_WHITESPACE) -# RE2C_TARGET(Name RE2CInput RE2COutput [COMPILE_FLAGS ]) -# which creates a custom command to generate the file from -# the file. If COMPILE_FLAGS option is specified, the next -# parameter is added to the re2c command line. Name is an alias used to -# get details of this custom command. + if(NOT ${RE2C_version_result} EQUAL 0) + message(SEND_ERROR + "Command \"${RE2C_EXECUTABLE} -v\" failed with output:\n${RE2C_version_output}\n${RE2C_version_error}") + else() + string(REGEX REPLACE "^re2c ([0-9]+[^ ]*)( .*)?$" "\\1" RE2C_VERSION "${RE2C_version_output}") + endif() -# This module also defines a macro: -# ADD_RE2C_LEMON_DEPENDENCY(RE2CTarget LemonTarget) -# which adds the required dependency between a scanner and a parser -# where and are the first parameters of -# respectively RE2C_TARGET and LEMON_TARGET macros. -# -# ==================================================================== -# Example: -# -# find_package(LEMON) -# find_package(RE2C) -# -# LEMON_TARGET(MyParser parser.y "${CMAKE_CURRENT_BINARY_DIR}/parser.cpp") -# RE2C_TARGET(MyScanner scanner.re "${CMAKE_CURRENT_BINARY_DIR}/scanner.cpp") -# ADD_RE2C_LEMON_DEPENDENCY(MyScanner MyParser) -# -# include_directories("${CMAKE_CURRENT_BINARY_DIR}") -# add_executable(Foo -# Foo.cc -# ${LEMON_MyParser_OUTPUTS} -# ${RE2C_MyScanner_OUTPUTS} -# ) -# ==================================================================== -# -#============================================================================= -# Copyright (c) 2010-2016 United States Government as represented by -# the U.S. Army Research Laboratory. -# 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. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#============================================================================= + # Provide a macro to generate custom build rules: -#============================================================ -# RE2C_TARGET (public macro) -#============================================================ -# -# TODO - rework this macro to make use of CMakeParseArguments, see -# http://www.cmake.org/pipermail/cmake/2012-July/051309.html -if(NOT COMMAND RE2C_TARGET) - macro(RE2C_TARGET Name Input Output) - set(RE2C_TARGET_usage "RE2C_TARGET( [COMPILE_FLAGS ]") - if(${ARGC} GREATER 3) - if(${ARGC} EQUAL 5) - if("${ARGV3}" STREQUAL "COMPILE_FLAGS") - set(RE2C_EXECUTABLE_opts "${ARGV4}") - SEPARATE_ARGUMENTS(RE2C_EXECUTABLE_opts) + # RE2C_TARGET(Name RE2CInput RE2COutput [COMPILE_FLAGS ]) + # which creates a custom command to generate the file from + # the file. If COMPILE_FLAGS option is specified, the next + # parameter is added to the re2c command line. Name is an alias used to + # get details of this custom command. + + # This module also defines a macro: + # ADD_RE2C_LEMON_DEPENDENCY(RE2CTarget LemonTarget) + # which adds the required dependency between a scanner and a parser + # where and are the first parameters of + # respectively RE2C_TARGET and LEMON_TARGET macros. + # + # ==================================================================== + # Example: + # + # find_package(LEMON) + # find_package(RE2C) + # + # LEMON_TARGET(MyParser parser.y "${CMAKE_CURRENT_BINARY_DIR}/parser.cpp") + # RE2C_TARGET(MyScanner scanner.re "${CMAKE_CURRENT_BINARY_DIR}/scanner.cpp") + # ADD_RE2C_LEMON_DEPENDENCY(MyScanner MyParser) + # + # include_directories("${CMAKE_CURRENT_BINARY_DIR}") + # add_executable(Foo + # Foo.cc + # ${LEMON_MyParser_OUTPUTS} + # ${RE2C_MyScanner_OUTPUTS} + # ) + # ==================================================================== + # + #============================================================================= + # Copyright (c) 2010-2016 United States Government as represented by + # the U.S. Army Research Laboratory. + # 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. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + #============================================================================= + + #============================================================ + # RE2C_TARGET (public macro) + #============================================================ + # + if(NOT COMMAND RE2C_TARGET) + function(RE2C_TARGET Name RE2CInput RE2COutput) + set(_re2c_args COMPILE_FLAGS DEFINES_FILE) + cmake_parse_arguments(RE2C_TARGET_ARG "" "${_re2c_args}" "" ${ARGN}) + + if(NOT "${RE2C_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "") + message(SEND_ERROR "RE2C_TARGET( + [COMPILE_FLAGS ] + [DEFINES_FILE ])") + else() + if(NOT "${RE2C_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "") + set(RE2C_EXECUTABLE_opts "${RE2C_TARGET_ARG_COMPILE_FLAGS}") + separate_arguments(RE2C_EXECUTABLE_opts) else() - message(SEND_ERROR ${RE2C_TARGET_usage}) + set(RE2C_EXECUTABLE_opts "") endif() - else() - message(SEND_ERROR ${RE2C_TARGET_usage}) + + if(NOT "${RE2C_TARGET_ARG_DEFINES_FILE}" STREQUAL "") + list(APPEND RE2C_EXECUTABLE_opts -t ${RE2C_TARGET_ARG_DEFINES_FILE}) + endif() + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${RE2COutput} + COMMAND ${RE2C_EXECUTABLE} + ARGS ${RE2C_EXECUTABLE_opts} -o ${RE2COutput} ${CMAKE_CURRENT_SOURCE_DIR}/${RE2CInput} + DEPENDS ${RE2CInput} + COMMENT "[RE2C][${Name}] Building scanner with ${RE2C_EXECUTABLE}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + + # TODO: check, for generated sources headers should be included in outputs + set(RE2C_${Name}_DEFINED TRUE PARENT_SCOPE) + set(RE2C_${Name}_OUTPUTS ${RE2COutput} PARENT_SCOPE) + if("${RE2C_TARGET_ARG_DEFINES_FILE}" STREQUAL "") + set(RE2C_${Name}_OUTPUT_HEADER "" PARENT_SCOPE) + else() + set(RE2C_${Name}_OUTPUT_HEADER "${RE2C_TARGET_ARG_DEFINES_FILE}" PARENT_SCOPE) + endif() + set(RE2C_${Name}_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE) endif() - endif() - - add_custom_command(OUTPUT ${Output} - COMMAND ${RE2C_EXECUTABLE} - ARGS ${RE2C_EXECUTABLE_opts} -o${Output} ${Input} - DEPENDS ${Input} ${RE2C_EXECUTABLE_TARGET} - COMMENT "[RE2C][${Name}] Building scanner with ${RE2C_EXECUTABLE}" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") - - set(RE2C_${Name}_DEFINED TRUE) - set(RE2C_${Name}_OUTPUTS ${Output}) - set(RE2C_${Name}_INPUT ${Input}) - set(RE2C_${Name}_COMPILE_FLAGS ${RE2C_EXECUTABLE_opts}) - set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${Output}") - endmacro(RE2C_TARGET) -endif(NOT COMMAND RE2C_TARGET) -#============================================================ - -#============================================================ -# ADD_RE2C_LEMON_DEPENDENCY (public macro) -#============================================================ -# -if(NOT COMMAND ADD_RE2C_LEMON_DEPENDENCY) - macro(ADD_RE2C_LEMON_DEPENDENCY RE2CTarget LemonTarget) - - if(NOT RE2C_${RE2CTarget}_OUTPUTS) - message(SEND_ERROR "RE2C target `${RE2CTarget}' does not exists.") - endif() - - if(NOT LEMON_${LemonTarget}_HDR) - message(SEND_ERROR "Lemon target `${LemonTarget}' does not exists.") - endif() - - set_source_files_properties(${RE2C_${RE2CTarget}_OUTPUTS} - PROPERTIES OBJECT_DEPENDS ${LEMON_${LemonTarget}_HDR}) - endmacro(ADD_RE2C_LEMON_DEPENDENCY) -endif(NOT COMMAND ADD_RE2C_LEMON_DEPENDENCY) -#============================================================ + + endfunction(RE2C_TARGET) + endif(NOT COMMAND RE2C_TARGET) + #============================================================ + + #============================================================ + # ADD_RE2C_LEMON_DEPENDENCY (public macro) + #============================================================ + # + if(NOT COMMAND ADD_RE2C_LEMON_DEPENDENCY) + function(ADD_RE2C_LEMON_DEPENDENCY RE2CTarget LemonTarget) + + if(NOT RE2C_${RE2CTarget}_OUTPUTS) + message(SEND_ERROR "RE2C target `${RE2CTarget}' does not exists.") + endif() + + if(NOT LEMON_${LemonTarget}_OUTPUT_HEADER) + message(SEND_ERROR "Lemon target `${LemonTarget}' does not exists.") + endif() + + set_source_files_properties(${RE2C_${RE2CTarget}_OUTPUTS} + PROPERTIES OBJECT_DEPENDS ${LEMON_${LemonTarget}_OUTPUT_HEADER}) + endfunction(ADD_RE2C_LEMON_DEPENDENCY) + endif(NOT COMMAND ADD_RE2C_LEMON_DEPENDENCY) + #============================================================ + +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(RE2C REQUIRED_VARS RE2C_EXECUTABLE + VERSION_VAR RE2C_VERSION) # RE2C_Util.cmake ends here diff --git a/cmake/Generated_Source_Utils.cmake b/cmake/Generated_Source_Utils.cmake deleted file mode 100644 index 601f92364..000000000 --- a/cmake/Generated_Source_Utils.cmake +++ /dev/null @@ -1,67 +0,0 @@ -# Utility routines for managing generated files with CMake - -macro(MD5 filename md5sum) - file(READ "${filename}" RAW_MD5_FILE) - string(REGEX REPLACE "\r" "" STRIPPED_MD5_FILE "${RAW_MD5_FILE}") - string(MD5 ${md5sum} "${STRIPPED_MD5_FILE}") -endmacro(MD5) - -macro(FILEVAR filename var) - string(REGEX REPLACE "[^a-zA-Z0-9]" "_" ${var} ${filename}) -endmacro(FILEVAR) - -macro(VERIFY_FILES filelist warn resultvar) - set(${resultvar} 1) - foreach(fileitem ${filelist}) - # Deal with absolute and relative paths a bit differently - get_filename_component(ITEM_ABS_PATH "${fileitem}" ABSOLUTE) - if("${fileitem}" STREQUAL "${ITEM_ABS_PATH}") - set(filefullname "${fileitem}") - else("${fileitem}" STREQUAL "${ITEM_ABS_PATH}") - set(filefullname "${CURRENT_SOURCE_DIR}/${fileitem}") - endif("${fileitem}" STREQUAL "${ITEM_ABS_PATH}") - get_filename_component(filename "${fileitem}" NAME) - # Got filename components sorted - proceed - if(NOT EXISTS ${filefullname}) - message(FATAL_ERROR "Attempted to verify non-existant file ${filefullname}") - endif(NOT EXISTS ${filefullname}) - FILEVAR(${filename} filevar) - if(NOT baseline_${filevar}_md5) - message(FATAL_ERROR "No baseline MD5 available for ${filename} - baseline_${filevar}_md5 is not defined") - endif(NOT baseline_${filevar}_md5) - MD5(${filefullname} ${filevar}_md5) - if(NOT "${${filevar}_md5}" STREQUAL "${baseline_${filevar}_md5}") - if("${warn}" STREQUAL "1") - message("\n${filename} differs from baseline: baseline md5 hash is ${baseline_${filevar}_md5} and current hash is ${${filevar}_md5}\n") - endif("${warn}" STREQUAL "1") - set(${resultvar} 0) - endif(NOT "${${filevar}_md5}" STREQUAL "${baseline_${filevar}_md5}") - endforeach(fileitem ${filelist}) -endmacro(VERIFY_FILES filelist resultvar) - -macro(WRITE_MD5_SUMS filelist outfile) - foreach(fileitem ${filelist}) - # Deal with absolute and relative paths a bit differently - get_filename_component(ITEM_ABS_PATH "${fileitem}" ABSOLUTE) - if("${fileitem}" STREQUAL "${ITEM_ABS_PATH}") - set(filefullname "${fileitem}") - else("${fileitem}" STREQUAL "${ITEM_ABS_PATH}") - set(filefullname "${CURRENT_SOURCE_DIR}/${fileitem}") - endif("${fileitem}" STREQUAL "${ITEM_ABS_PATH}") - get_filename_component(filename "${fileitem}" NAME) - # Got filename components sorted - proceed - if(NOT EXISTS ${filefullname}) - message(FATAL_ERROR "Attempted to get MD5 sum of non-existant file ${filefullname}") - endif(NOT EXISTS ${filefullname}) - FILEVAR(${filename} filevar) - MD5(${filefullname} ${filevar}_md5) - file(APPEND ${outfile} "set(baseline_${filevar}_md5 ${${filevar}_md5})\n") - endforeach(fileitem ${filelist}) -endmacro(WRITE_MD5_SUMS) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/cmake/Path_Setup.cmake b/cmake/Path_Setup.cmake new file mode 100644 index 000000000..f5db3b411 --- /dev/null +++ b/cmake/Path_Setup.cmake @@ -0,0 +1,164 @@ +# Copyright (c) 2010-2020 United States Government as represented by +# the U.S. Army Research Laboratory. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. 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. +# +# 3. The name of the author may not be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS +# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +#--------------------------------------------------------------------- +# Define relative install locations. Don't set these if they have already +# been set by some other means (like a higher level CMakeLists.txt file +# including this one). + +# The location in which to install BRL-CAD executables. +if(NOT BIN_DIR) + set(BIN_DIR bin) +endif(NOT BIN_DIR) + +# Define a relative path that will "reset" a path back to +# the point before BIN_DIR was appended. This is primarily +# useful when working with generator expressions +unset(RBIN_DIR CACHE) +set(LBIN_DIR "${BIN_DIR}") +while (NOT "${LBIN_DIR}" STREQUAL "") + get_filename_component(LBDIR "${LBIN_DIR}" DIRECTORY) + set(LBIN_DIR "${LBDIR}") + if ("${RBIN_DIR}" STREQUAL "") + set(RBIN_DIR "..") + else ("${RBIN_DIR}" STREQUAL "") + set(RBIN_DIR "../${RBIN_DIR}") + endif ("${RBIN_DIR}" STREQUAL "") +endwhile (NOT "${LBIN_DIR}" STREQUAL "") + +# The location in which to install BRL-CAD libraries. +if(NOT LIB_DIR) + set(LIB_DIR lib) +endif(NOT LIB_DIR) +if(NOT LIBEXEC_DIR) + set(LIBEXEC_DIR libexec) +endif(NOT LIBEXEC_DIR) + +# The location in which to install BRL-CAD header files. +if(NOT INCLUDE_DIR) + set(INCLUDE_DIR include) +endif(NOT INCLUDE_DIR) + +# The location in which to install BRL-CAD data files +if(NOT DATA_DIR) + set(DATA_DIR share) +endif(NOT DATA_DIR) + +# The location in which to install BRL-CAD documentation files +if(NOT DOC_DIR) + set(DOC_DIR ${DATA_DIR}/doc) +endif(NOT DOC_DIR) + +# The location in which to install BRL-CAD Manual pages +if(NOT MAN_DIR) + set(MAN_DIR ${DATA_DIR}/man) +endif(NOT MAN_DIR) + +# Make sure no absolute paths have been supplied to these variables +set(INSTALL_DIRS BIN INCLUDE LIB LIBEXEC DATA MAN DOC) +foreach(instdir ${INSTALL_DIRS}) + get_filename_component(instdir_full ${${instdir}_DIR} ABSOLUTE) + if("${${instdir}_DIR}" STREQUAL "${instdir_full}") + message(FATAL_ERROR "Error - absolute path supplied for ${instdir}_DIR. This path must be relative - e.g. \"bin\" instead of \"/usr/bin\"") + set(HAVE_INSTALL_DIR_FULL_PATH 1) + endif("${${instdir}_DIR}" STREQUAL "${instdir_full}") +endforeach(instdir ${INSTALL_DIRS}) + +#--------------------------------------------------------------------- +# Output directories - this is where built library and executable +# files will be placed after building but prior to install. The +# necessary variables change between single and multi configuration +# build systems, so it is necessary to handle both cases on a +# conditional basis. + +if(NOT CMAKE_CONFIGURATION_TYPES) + # If we're not doing multi-configuration, just set the three main + # variables to the correct values. + if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${${PROJECT_NAME}_BINARY_DIR}/${LIB_DIR} 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 ${${PROJECT_NAME}_BINARY_DIR}/${LIB_DIR} 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 ${${PROJECT_NAME}_BINARY_DIR}/${BIN_DIR} CACHE INTERNAL "Single output directory for building all executables.") + endif(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY) +else(NOT CMAKE_CONFIGURATION_TYPES) + # Multi-configuration is more difficult. Not only do we need to + # properly set the output directories, but we also need to + # identify the "toplevel" directory for each configuration so + # we can place files, documentation, etc. in the correct + # relative positions. Because files may be placed by CMake + # without a build target to put them in their proper relative build + # directory position using these paths, we must fully qualify them + # without using CMAKE_CFG_INTDIR. + # + # We define directories that may not be quite "standard" + # for a particular build tool - for example, native VS2010 projects use + # another directory to denote CPU type being compiled for - but CMake only + # supports multi-configuration setups having multiple configurations, + # not multiple compilers. + # + # One additional wrinkle we must watch for here is the case where + # a multi-configuration setup uses "." for its internal directory - + # if that's the case, we need to just set the various config output + # directories to the same value. + set(CFG_ROOT ${${PROJECT_NAME}_BINARY_DIR}) + foreach(CFG_TYPE ${CMAKE_CONFIGURATION_TYPES}) + if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + set(CFG_ROOT ${${PROJECT_NAME}_BINARY_DIR}/${CFG_TYPE}) + endif(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + string(TOUPPER "${CFG_TYPE}" CFG_TYPE_UPPER) + if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE_UPPER}) + set("CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE_UPPER}" ${CFG_ROOT}/${LIB_DIR} CACHE INTERNAL "Single output directory for building ${CFG_TYPE} libraries.") + endif(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CFG_TYPE_UPPER}) + if(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE_UPPER}) + set("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE_UPPER}" ${CFG_ROOT}/${LIB_DIR} CACHE INTERNAL "Single output directory for building ${CFG_TYPE} archives.") + endif(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CFG_TYPE_UPPER}) + if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE_UPPER}) + set("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE_UPPER}" ${CFG_ROOT}/${BIN_DIR} CACHE INTERNAL "Single output directory for building ${CFG_TYPE} executables.") + endif(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CFG_TYPE_UPPER}) + if(NOT DEFINED CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}) + set("CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}" ${CFG_ROOT} CACHE INTERNAL "Toplevel binary dir for ${CFG_TYPE} building.") + endif(NOT DEFINED CMAKE_BINARY_DIR_${CFG_TYPE_UPPER}) + if(NOT DEFINED ${PROJECT_NAME}_BINARY_DIR_${CFG_TYPE_UPPER}) + set("${PROJECT_NAME}_BINARY_DIR_${CFG_TYPE_UPPER}" ${CFG_ROOT} CACHE INTERNAL "Toplevel binary dir for ${CFG_TYPE} building.") + endif(NOT DEFINED ${PROJECT_NAME}_BINARY_DIR_${CFG_TYPE_UPPER}) + endforeach() +endif(NOT CMAKE_CONFIGURATION_TYPES) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 diff --git a/cmake/SC_Build_opts.cmake b/cmake/SC_Build_opts.cmake deleted file mode 100644 index 5a3661e45..000000000 --- a/cmake/SC_Build_opts.cmake +++ /dev/null @@ -1,174 +0,0 @@ -# BIN and LIB directories -if(NOT DEFINED BIN_DIR) - set(BIN_DIR bin) -endif(NOT DEFINED BIN_DIR) - -if(NOT DEFINED LIB_DIR) - set(LIB_DIR lib) -endif(NOT DEFINED LIB_DIR) - -# 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) - -# Should we use C++11? -OPTION_WITH_DEFAULT(SC_ENABLE_CXX11 "Build with C++ 11 features" ON) - -# Get version from git -OPTION_WITH_DEFAULT(SC_GIT_VERSION "Build using version from git" ON) - -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) - -#--------------------------------------------------------------------- -# Executable install option -OPTION_WITH_DEFAULT(SC_SKIP_EXEC_INSTALL "Skip installing executables" OFF) -if(SC_SKIP_EXEC_INSTALL) - set(SC_EXEC_NOINSTALL "NO_INSTALL") -endif(SC_SKIP_EXEC_INSTALL) - -#--------------------------------------------------------------------- -# 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 ") - 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 - diff --git a/cmake/SC_CXX_schema_macros.cmake b/cmake/SC_CXX_schema_macros.cmake index ddb267053..eab9174a7 100644 --- a/cmake/SC_CXX_schema_macros.cmake +++ b/cmake/SC_CXX_schema_macros.cmake @@ -27,19 +27,16 @@ 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) + SC_ADDEXEC(p21read_${PROJECT_NAME} SOURCES "${RELATIVE_PATH_COMPONENT}/src/test/p21read/p21read.cc;${RELATIVE_PATH_COMPONENT}/src/test/p21read/sc_benchmark.cc" LINK_LIBRARIES ${PROJECT_NAME} stepdai stepcore stepeditor steputils TESTABLE) if(NOT WIN32) - 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) + SC_ADDEXEC(lazy_${PROJECT_NAME} SOURCES "${RELATIVE_PATH_COMPONENT}/src/cllazyfile/lazy_test.cc;${RELATIVE_PATH_COMPONENT}/src/cllazyfile/sc_benchmark.cc" LINK_LIBRARIES ${PROJECT_NAME} steplazyfile stepdai stepcore stepeditor steputils TESTABLE) endif(NOT WIN32) #add user-defined executables foreach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS}) get_filename_component(name ${src} NAME_WE) get_filename_component(path ${src} ABSOLUTE) - SC_ADDEXEC(${name}_${PROJECT_NAME} "${src}" "${PROJECT_NAME};stepdai;stepcore;stepeditor;steputils;base" "TESTABLE") - add_dependencies(${name}_${PROJECT_NAME} version_string) + SC_ADDEXEC(${name}_${PROJECT_NAME} SOURCES ${src} LINK_LIBRARIES ${PROJECT_NAME} stepdai stepcore stepeditor steputils TESTABLE) #set_target_properties(${name}_${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${${PROJECT_NAME}_COMPILE_FLAGS} -I${path}") endforeach(src ${SC_SDAI_ADDITIONAL_EXES_SRCS}) ENDMACRO(SCHEMA_EXES) @@ -92,12 +89,36 @@ macro(SCHEMA_TARGETS expFile schemaName sourceFiles) ) 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 + ${SC_SOURCE_DIR}/src/clutils ${SC_SOURCE_DIR}/src/clstepcore ${SC_SOURCE_DIR}/src/cllazyfile + ${SC_SOURCE_DIR}/src/cllazyfile/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(BUILD_SHARED_LIBS) + SC_ADDLIB(${PROJECT_NAME} SHARED SOURCES ${sourceFiles} LINK_LIBRARIES stepdai stepcore stepeditor steputils TESTABLE) + add_dependencies(${PROJECT_NAME} generate_cpp_${PROJECT_NAME}) + if(WIN32) + target_compile_definitions("${PROJECT_NAME}" PRIVATE SC_SCHEMA_DLL_EXPORTS) + if(MSVC) + target_compile_options("${PROJECT_NAME}" PRIVATE "/bigobj") + endif() + endif() + # TODO - ideally we would avoid generating code that triggers this warning, but figuring out + # how to do so is a non-trivial exercise. In the meantime, suppress the (very verbose) warnings + # we get due to this issue so it doesn't mask other problems. + if(${CMAKE_C_COMPILER_ID} STREQUAL "GNU") + target_compile_options("${PROJECT_NAME}" PRIVATE "-Wno-ignored-qualifiers") + endif() + endif() + + if($CACHE{SC_BUILD_STATIC_LIBS}) + SC_ADDLIB(${PROJECT_NAME}-static STATIC SOURCES ${sourceFiles} LINK_LIBRARIES stepdai-static stepcore-static stepeditor-static steputils-static TESTABLE) + add_dependencies(${PROJECT_NAME}-static generate_cpp_${PROJECT_NAME}) + target_compile_definitions("${PROJECT_NAME}-static" PRIVATE SC_STATIC) + if(MSVC) + target_compile_options("${PROJECT_NAME}-static" PRIVATE "/bigobj") + endif() + endif() + SCHEMA_EXES() SCHEMA_TESTS() diff --git a/cmake/SC_Config_Headers.cmake b/cmake/SC_Config_Headers.cmake index 2ed3ba6e5..68f1c37ad 100644 --- a/cmake/SC_Config_Headers.cmake +++ b/cmake/SC_Config_Headers.cmake @@ -1,29 +1,11 @@ -# 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}") +# create config.h include(CheckLibraryExists) include(CheckIncludeFile) -include(CheckFunctionExists) +include(CheckSymbolExists) include(CheckTypeSize) include(CMakePushCheckState) +include(CheckCSourceCompiles) include(CheckCXXSourceRuns) CHECK_INCLUDE_FILE(ndir.h HAVE_NDIR_H) @@ -37,10 +19,13 @@ 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) +# ensure macro functions are captured +CHECK_SYMBOL_EXISTS(abs "stdlib.h" HAVE_ABS) +CHECK_SYMBOL_EXISTS(memcpy "string.h" HAVE_MEMCPY) +CHECK_SYMBOL_EXISTS(memmove "string.h" HAVE_MEMMOVE) +CHECK_SYMBOL_EXISTS(getopt "getopt.h" HAVE_GETOPT) +CHECK_SYMBOL_EXISTS(snprintf "stdio.h" HAVE_SNPRINTF) +CHECK_SYMBOL_EXISTS(vsnprintf "stdio.h" HAVE_VSNPRINTF) CHECK_TYPE_SIZE("ssize_t" SSIZE_T) @@ -80,7 +65,7 @@ std::cout << \"1s is \"<< std::chrono::duration_cast( set( TEST_NULLPTR " #include std::nullptr_t f() {return nullptr;} -int main() {return !!f();} +int main() {return !(f() == f());} " ) cmake_push_check_state() if( UNIX ) @@ -92,37 +77,9 @@ int main() {return !!f();} cmake_pop_check_state() endif(SC_ENABLE_CXX11) -# 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. -if(SC_GIT_VERSION) - 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 - 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 -else(SC_GIT_VERSION) - set(VER_HDR " - #ifndef SC_VERSION_STRING - #define SC_VERSION_STRING - static char sc_version[512] = {\"${SC_VERSION}\"}; - #endif" - ) - file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h "${VER_HDR}") -endif(SC_GIT_VERSION) -set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${INCLUDE_INSTALL_DIR}/sc_version_string.h - PROPERTIES GENERATED TRUE - HEADER_FILE_ONLY TRUE ) +# Now that all the tests are done, configure the config.h file: +configure_file(${CMAKE_SOURCE_DIR}/include/config.h.in ${SC_BINARY_DIR}/${INCLUDE_DIR}/config.h.gen) +execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SC_BINARY_DIR}/${INCLUDE_DIR}/config.h.gen ${SC_BINARY_DIR}/${INCLUDE_DIR}/config.h) # Local Variables: # tab-width: 8 diff --git a/cmake/SC_Regenerate.cmake b/cmake/SC_Regenerate.cmake index 513b4787a..cab3b049c 100644 --- a/cmake/SC_Regenerate.cmake +++ b/cmake/SC_Regenerate.cmake @@ -1,4 +1,4 @@ -# The Express parser uses the tools Perplex, RE2C and Lemon to generate code +# The Express parser uses the tools 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. @@ -10,45 +10,38 @@ # 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") + +set(_valid_gen_states AUTO ON OFF) +set(_verbosity "QUIET") + +set(SC_GENERATE_LEXER_PARSER "AUTO" CACHE + STRING "Use Perplex, RE2C and Lemon to generate C source code.") +set_property(CACHE SC_GENERATE_LEXER_PARSER PROPERTY STRINGS ${_valid_gen_states}) +string(TOUPPER "${SC_GENERATE_LEXER_PARSER}" SC_GENERATE_LEXER_PARSER) + +if(NOT "${SC_GENERATE_LEXER_PARSER}" IN_LIST _valid_gen_states) 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") +endif() # If the generators have not been turned off, we need to check for them if(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF") + # NOTE: lemon doesn't have a stable versioning system (it's always 1) 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(LEMON_FOUND AND RE2C_FOUND) 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) + message(".. Found re2c, and lemon - can regenerate lexer/parser if necessary") + else() 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") + message(FATAL_ERROR "\nSC_GENERATE_LEXER_PARSER set to ON, but couldn't find lemon/re2c") 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) + endif() else(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF") set(SC_GENERATE_LP_SOURCES 0) endif(NOT "${SC_GENERATE_LEXER_PARSER}" STREQUAL "OFF") diff --git a/cmake/SC_Targets.cmake b/cmake/SC_Targets.cmake index d451658d2..cb2d11dd6 100644 --- a/cmake/SC_Targets.cmake +++ b/cmake/SC_Targets.cmake @@ -1,150 +1,86 @@ +macro(SC_ADDEXEC execname) + set(_addexec_opts NO_INSTALL TESTABLE) + set(_addexec_multikw SOURCES LINK_LIBRARIES) + string(TOUPPER "SC_ADDEXEC_${execname}_ARG" _arg_prefix) + cmake_parse_arguments(${_arg_prefix} "${_addexec_opts}" "" "${_addexec_multikw}" ${ARGN}) -# 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() - set_property(TARGET ${libname} APPEND PROPERTY COMPILE_DEFINITIONS "${export}") - endif(MSVC OR BORLAND) -endmacro(DEFINE_DLL_EXPORTS libname) + if(NOT DEFINED "${_arg_prefix}_SOURCES") + message(SEND_ERROR "SC_ADDEXEC usage error!") + endif() -# set compile definitions for dll imports on windows -macro(DEFINE_DLL_IMPORTS tgt libs) - if(MSVC OR BORLAND) - set(imports "") - foreach(lib ${libs}) - string(REGEX REPLACE "lib" "" shortname "${lib}") - string(REGEX REPLACE "step" "" LOWERCORE "${shortname}") - string(TOUPPER ${LOWERCORE} UPPER_CORE) - list(APPEND imports "SC_${UPPER_CORE}_DLL_IMPORTS") - endforeach(lib ${libs}) - set_property(TARGET ${tgt} APPEND PROPERTY COMPILE_DEFINITIONS "${imports}") - endif(MSVC OR BORLAND) -endmacro(DEFINE_DLL_IMPORTS tgt libs) + add_executable(${execname} ${${_arg_prefix}_SOURCES}) -#SC_ADDEXEC(execname "source files" "linked libs" ["TESTABLE"] ["NO_INSTALL"]) -macro(SC_ADDEXEC execname srcslist libslist) + if(DEFINED "${_arg_prefix}_LINK_LIBRARIES") + foreach(_lib ${${_arg_prefix}_LINK_LIBRARIES}) + if($CACHE{SC_STATIC_UTILS}) + if(NOT $ STREQUAL "STATIC_LIBRARY") + message(SEND_ERROR "SC_ADDEXEC usage error - expected STATIC LINK_LIBRARIES targets (${_lib})") + endif() + endif() + target_link_libraries(${execname} ${_lib}) + endforeach() + endif() - string(TOUPPER "${execname}" EXECNAME_UPPER) - if(${ARGC} GREATER 3) - CMAKE_PARSE_ARGUMENTS(${EXECNAME_UPPER} "NO_INSTALL;TESTABLE" "" "" ${ARGN}) - endif(${ARGC} GREATER 3) - - 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 - if(NOT ${EXECNAME_UPPER}_NO_INSTALL AND NOT ${EXECNAME_UPPER}_TESTABLE) + if(NOT ${_arg_prefix}_NO_INSTALL AND NOT ${_arg_prefix}_TESTABLE) install(TARGETS ${execname} RUNTIME DESTINATION ${BIN_DIR} LIBRARY DESTINATION ${LIB_DIR} - ARCHIVE DESTINATION ${LIB_DIR} - ) - endif(NOT ${EXECNAME_UPPER}_NO_INSTALL AND NOT ${EXECNAME_UPPER}_TESTABLE) - if(NOT SC_ENABLE_TESTING AND ${EXECNAME_UPPER}_TESTABLE) - set_target_properties( ${execname} PROPERTIES EXCLUDE_FROM_ALL ON ) - endif(NOT SC_ENABLE_TESTING AND ${EXECNAME_UPPER}_TESTABLE) - - # 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) + ARCHIVE DESTINATION ${LIB_DIR} + ) + endif() -endmacro(SC_ADDEXEC execname srcslist libslist) + if(NOT SC_ENABLE_TESTING AND ${_arg_prefix}_TESTABLE) + set_target_properties(${execname} PROPERTIES EXCLUDE_FROM_ALL ON) + endif() +endmacro() -#SC_ADDLIB(libname "source files" "linked libs" ["TESTABLE"] ["NO_INSTALL"] ["SO_SRCS ..."] ["STATIC_SRCS ..."]) -macro(SC_ADDLIB libname srcslist libslist) +macro(SC_ADDLIB _addlib_target) + set(_addlib_opts SHARED STATIC NO_INSTALL TESTABLE) + set(_addlib_multikw SOURCES LINK_LIBRARIES) + string(TOUPPER "SC_ADDLIB_${libname}_ARG" _arg_prefix) + cmake_parse_arguments(${_arg_prefix} "${_addlib_opts}" "" "${_addlib_multikw}" ${ARGN}) - string(TOUPPER "${libname}" LIBNAME_UPPER) - if(${ARGC} GREATER 3) - CMAKE_PARSE_ARGUMENTS(${LIBNAME_UPPER} "NO_INSTALL;TESTABLE" "" "SO_SRCS;STATIC_SRCS" ${ARGN}) - endif(${ARGC} GREATER 3) + if(NOT DEFINED ${_arg_prefix}_SOURCES) + message(SEND_ERROR "SC_ADDLIB usage error!") + endif() - string(REGEX REPLACE "-framework;" "-framework " libslist "${libslist1}") - if(SC_BUILD_SHARED_LIBS) - add_library(${libname} SHARED ${srcslist} ${${LIBNAME_UPPER}_SO_SRCS}) - 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}) - if(NOT ${LIBNAME_UPPER}_NO_INSTALL AND NOT ${LIBNAME_UPPER}_TESTABLE) - install(TARGETS ${libname} - RUNTIME DESTINATION ${BIN_DIR} - LIBRARY DESTINATION ${LIB_DIR} - ARCHIVE DESTINATION ${LIB_DIR} - ) - endif(NOT ${LIBNAME_UPPER}_NO_INSTALL AND NOT ${LIBNAME_UPPER}_TESTABLE) - if(NOT SC_ENABLE_TESTING AND ${LIBNAME_UPPER}_TESTABLE) - set_target_properties( ${libname} PROPERTIES EXCLUDE_FROM_ALL ON ) - endif(NOT SC_ENABLE_TESTING AND ${LIBNAME_UPPER}_TESTABLE) - 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} ${${LIBNAME_UPPER}_STATIC_SRCS}) - 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) - if(NOT ${LIBNAME_UPPER}_NO_INSTALL AND NOT ${LIBNAME_UPPER}_TESTABLE) - install(TARGETS ${libname}-static - RUNTIME DESTINATION ${BIN_DIR} - LIBRARY DESTINATION ${LIB_DIR} - ARCHIVE DESTINATION ${LIB_DIR} - ) - endif(NOT ${LIBNAME_UPPER}_NO_INSTALL AND NOT ${LIBNAME_UPPER}_TESTABLE) - if(NOT SC_ENABLE_TESTING AND ${LIBNAME_UPPER}_TESTABLE) - set_target_properties( ${libname}-static PROPERTIES EXCLUDE_FROM_ALL ON ) - endif(NOT SC_ENABLE_TESTING AND ${LIBNAME_UPPER}_TESTABLE) + if(${_arg_prefix}_SHARED) + add_library(${_addlib_target} SHARED ${${_arg_prefix}_SOURCES}) + if(OPENBSD) + set_target_properties(${_addlib_target} PROPERTIES VERSION ${SC_VERSION_MAJOR}.${SC_VERSION_MINOR}) + else(OPENBSD) + set_target_properties(${_addlib_target} PROPERTIES VERSION ${SC_VERSION} SOVERSION ${SC_VERSION_MAJOR}) + endif(OPENBSD) if(APPLE) - set_target_properties(${staticlibname} PROPERTIES LINK_FLAGS "-flat_namespace -undefined suppress") + set_target_properties(${_addlib_target} 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) + elseif(${_arg_prefix}_STATIC) + add_library(${_addlib_target} STATIC ${${_arg_prefix}_SOURCES}) + target_compile_definitions(${_addlib_target} PRIVATE SC_STATIC) + else() + message(SEND_ERROR "SC_ADDLIB usage error!") + endif() + + if(DEFINED ${_arg_prefix}_LINK_LIBRARIES) + foreach(_lib ${${_arg_prefix}_LINK_LIBRARIES}) + if(${_arg_prefix}_STATIC AND TARGET ${_lib}) + get_property(_libtype TARGET ${_lib} PROPERTY TYPE) + if(NOT ${_libtype} STREQUAL "STATIC_LIBRARY") + message(SEND_ERROR "SC_ADDLIB usage error - expected (static) LINK_LIBRARIES targets (${_lib})") + endif() + endif() + target_link_libraries(${_addlib_target} ${_lib}) + endforeach() + endif() + + if(NOT ${_arg_prefix}_NO_INSTALL AND NOT ${_arg_prefix}_TESTABLE) + install(TARGETS ${_addlib_target} + RUNTIME DESTINATION ${BIN_DIR} + LIBRARY DESTINATION ${LIB_DIR} + ARCHIVE DESTINATION ${LIB_DIR} + ) + endif() +endmacro() # Local Variables: # tab-width: 8 diff --git a/cmake/md5_gen.cmake.in b/cmake/md5_gen.cmake.in deleted file mode 100644 index 9d664baa0..000000000 --- a/cmake/md5_gen.cmake.in +++ /dev/null @@ -1,35 +0,0 @@ -# Inherit the parent CMake setting -set(CURRENT_SOURCE_DIR @CMAKE_CURRENT_SOURCE_DIR@) -set(CURRENT_BINARY_DIR @CMAKE_CURRENT_BINARY_DIR@) - -# Define a variety of convenience routines -include(@PROJECT_CMAKE_DIR@/Generated_Source_Utils.cmake) - -# The following steps are executed to sync generated sources: -# -# 1. Create a new verification_info.cmake file and populate -# it with the MD5 sums for current files. -# -# 2. Overwrite the original cached verification_info.cmake -# and generated files with the new ones. If LOCKED_SOURCE_DIR -# is ON, this step will not be carried out - instead, an -# informational message with manual updating instructions -# will be printed. - -set(new_info_file "${CURRENT_BINARY_DIR}/verification_info.cmake") - - -file(WRITE ${new_info_file} "# Autogenerated verification information\n") - -# Handle input files -set(input_files "@MD5_FILELIST@") -WRITE_MD5_SUMS("${input_files}" "${new_info_file}") - -message("New verification file created: ${new_info_file}") - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/cmake/md5_verify.cmake.in b/cmake/md5_verify.cmake.in deleted file mode 100644 index 5eb105337..000000000 --- a/cmake/md5_verify.cmake.in +++ /dev/null @@ -1,30 +0,0 @@ -# Inherit the parent CMake setting -set(DEBUGGING_GENERATED_SOURCES @DEBUGGING_GENERATED_SOURCES@) -set(CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@") - -# Include the file the provides the baseline against which -# current files will be compared - - include("@BASELINE_INFORMATION_FILE@") - - # Define a variety of convenience routines - include("@PROJECT_CMAKE_DIR@/Generated_Source_Utils.cmake") - - # Individually verify all of the files in question. - set(filelist "@MD5_FILELIST@") - VERIFY_FILES("${filelist}" 1 srcs_pass) - if(NOT srcs_pass) - if(NOT DEBUGGING_GENERATED_SOURCES) - message(FATAL_ERROR "Sources have been modified and md5 sums have not been updated. This generally indicates either\n a) an input file has been modified but generated files have not been updated, or\n b) genenerated files have been edited directly.\nTo clear the error:\n a) Copy the new generated sources from the build directory to the generated/ sources directory, use the _md5gen build target to create a new verifictation_info.cmake file, and copy verfication_info.cmake to generated/ as well.\n b) install Perplex/Re2C/LEMON and make the changes to the input file rather than the generated file.\nNote:\n If this is a debugging situation where multiple sequential tests must be conducted, temporarily set the variable DEBUGGING_GENERATED_SOURCES to ON during the CMake configure to disable this check.\nThis measure is necessary to ensure that compilations using either Perplex/Re2C/LEMON generation or the cached outputs of those tools produce consistent results.") - else(NOT DEBUGGING_GENERATED_SOURCES) - message(WARNING "Note: Sources have been modified and md5 sums have not been updated - build failure condition temporarily overridden by DEBUGGING_GENERATED_SOURCES setting.") - endif(NOT DEBUGGING_GENERATED_SOURCES) - endif(NOT srcs_pass) - - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/cmake/sc_version_string.cmake b/cmake/sc_version_string.cmake deleted file mode 100644 index 3c7f89927..000000000 --- a/cmake/sc_version_string.cmake +++ /dev/null @@ -1,92 +0,0 @@ -# creates sc_version_string.h, which defines sc_version() -# sc_version() returns a pretty commit description and a build timestamp. - -# only update the file if the git commit has changed, because whenever the file is updated files including the header must rebuild -# parallel rebuilds can result in race conditions and failures, particularly when running ctest in parallel - -# http://stackoverflow.com/questions/3780667 -# http://www.cmake.org/pipermail/cmake/2009-February/027014.html - -set(SC_IS_SUBBUILD "@SC_IS_SUBBUILD@") - -set(SC_VERSION_HEADER "${BINARY_DIR}/include/sc_version_string.h") - -#---------- find commit id ------------------ -#use git for a pretty commit id -#uses 'git describe --tags', so tags are required in the repo -#create a tag with 'git tag ' 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) - if(NOT SC_IS_SUBBUILD) - message(WARNING "Git not found. Build will contain revision info from ${VERS_FILE}.") - endif(NOT SC_IS_SUBBUILD) - 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) -endif() -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) - -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) -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" - ) - -#don't update the file unless somethig changed -file(WRITE ${SC_VERSION_HEADER}.tmp ${header_string}) -execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SC_VERSION_HEADER}.tmp ${SC_VERSION_HEADER}) -execute_process(COMMAND ${CMAKE_COMMAND} -E remove ${SC_VERSION_HEADER}.tmp) - -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 - diff --git a/cmake/schema_scanner/CMakeLists.txt b/cmake/schema_scanner/CMakeLists.txt index 13bbb24dd..20968ddb0 100644 --- a/cmake/schema_scanner/CMakeLists.txt +++ b/cmake/schema_scanner/CMakeLists.txt @@ -1,5 +1,5 @@ project(SC_SUBPROJECT_SCHEMA_SCANNER) -cmake_minimum_required(VERSION 2.8.7) +cmake_minimum_required(VERSION 3.12) if(NOT ("${CALLED_FROM}" STREQUAL "STEPCODE_CMAKELISTS" AND DEFINED SC_ROOT AND DEFINED SC_BUILDDIR)) message(" ${CALLED_FROM} ${SC_ROOT} ${SC_BUILDDIR}") @@ -16,12 +16,12 @@ 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/alloc.c ${SC_ROOT}/src/express/caseitem.c ${SC_ROOT}/src/express/dict.c ${SC_ROOT}/src/express/entity.c @@ -29,6 +29,7 @@ set(schema_scanner_src ${SC_ROOT}/src/express/exp_kw.c ${SC_ROOT}/src/express/expr.c ${SC_ROOT}/src/express/express.c + ${SC_ROOT}/src/express/factory.c ${SC_ROOT}/src/express/hash.c ${SC_ROOT}/src/express/lexact.c ${SC_ROOT}/src/express/linklist.c @@ -36,6 +37,7 @@ set(schema_scanner_src ${SC_ROOT}/src/express/object.c ${SC_ROOT}/src/express/info.c ${SC_ROOT}/src/express/resolve.c + ${SC_ROOT}/src/express/resolve2.c ${SC_ROOT}/src/express/schema.c ${SC_ROOT}/src/express/scope.c ${SC_ROOT}/src/express/stmt.c @@ -49,24 +51,20 @@ 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 ) +add_executable(schema_scanner ${schema_scanner_src}) + 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__) + target_compile_definitions(schema_scanner PUBLIC _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_WARNINGS) else() - add_definitions(-pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long) + target_compile_options(schema_scanner PUBLIC -pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long) endif() -add_definitions(-DSCHEMA_SCANNER) - -add_executable(schema_scanner ${schema_scanner_src}) +target_compile_definitions(schema_scanner PUBLIC SC_STATIC SCHEMA_SCANNER) # Local Variables: # tab-width: 8 diff --git a/cmake/schema_scanner/schemaScanner.cc b/cmake/schema_scanner/schemaScanner.cc index 9460733de..e37238415 100644 --- a/cmake/schema_scanner/schemaScanner.cc +++ b/cmake/schema_scanner/schemaScanner.cc @@ -14,20 +14,25 @@ */ extern "C" { -# include "expparse.h" -# include "expscan.h" -# include "express/scope.h" -# include "genCxxFilenames.h" -# include "sc_mkdir.h" - -# include - -# if defined( _WIN32 ) || defined ( __WIN32__ ) -# include -# define getcwd _getcwd -# else -# include -# endif +#define _XOPEN_SOURCE /* for S_IFDIR */ + +#include +#include +#include + +#include "expparse.h" +#include "expscan.h" +#include "express/scope.h" +#include "genCxxFilenames.h" + +#include + +#ifdef _WIN32 +# include +# define getcwd _getcwd +#else +# include +#endif } #include @@ -125,6 +130,30 @@ string makeShortName( const char * longName ) { return filename; } +/* 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 */ +static 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; +} + + /** 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 ) { @@ -220,7 +249,7 @@ void writeLists( const char * schemaName, stringstream & eh, stringstream & ei, cmLists.close(); - char pwd[BUFSIZ] = {0}; + char pwd[BUFSIZ+1] = {0}; if( getcwd( pwd, BUFSIZ ) ) { cout << pwd << "/" << shortName << endl; } else { @@ -244,7 +273,7 @@ void printSchemaFilenames( Schema sch ){ int ecount = 0, tcount = 0; DictionaryEntry de; - Generic x; + void *x; filenames_t fn; DICTdo_init( sch->symbol_table, &de ); while( 0 != ( x = DICTdo( &de ) ) ) { diff --git a/cmake/schema_scanner/schemaScanner.cmake b/cmake/schema_scanner/schemaScanner.cmake index 6b066339b..affe5c5cc 100644 --- a/cmake/schema_scanner/schemaScanner.cmake +++ b/cmake/schema_scanner/schemaScanner.cmake @@ -11,13 +11,8 @@ # 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( STATUS "Will not do unity build for this compiler. (SC_UNITY_BUILD=FALSE)") - set(SC_UNITY_BUILD FALSE) - else() - message( STATUS "Assuming compiler is capable of unity build. (SC_UNITY_BUILD=TRUE)") - set(SC_UNITY_BUILD TRUE) - endif(BORLAND) + message( STATUS "Assuming compiler is capable of unity build. (SC_UNITY_BUILD=TRUE)") + set(SC_UNITY_BUILD TRUE) message( STATUS "Override by setting SC_UNITY_BUILD; TRUE will result in faster build times but *huge* translation units and higher memory use in compilation.") else(NOT DEFINED SC_UNITY_BUILD) message( STATUS "Respecting user-defined SC_UNITY_BUILD value of ${SC_UNITY_BUILD}.") @@ -76,9 +71,9 @@ message( STATUS "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}) + install(PROGRAMS ${SCANNER_OUT_DIR}/schema_scanner.exe DESTINATION ${BIN_DIR}) else(WIN32) - install(PROGRAMS ${SCANNER_OUT_DIR}/schema_scanner DESTINATION ${BIN_INSTALL_DIR}) + install(PROGRAMS ${SCANNER_OUT_DIR}/schema_scanner DESTINATION ${BIN_DIR}) endif(WIN32) # macro SCHEMA_CMLIST @@ -106,5 +101,6 @@ macro(SCHEMA_CMLIST SCHEMA_FILE) 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. + # 2e6ee669 removed _schema, does this still work? configure_file(${SCHEMA_FILE} ${SCANNER_BUILD_DIR}/${_schema}) endmacro(SCHEMA_CMLIST SCHEMA_FILE) diff --git a/cmake/sync_generated.cmake.in b/cmake/sync_generated.cmake.in deleted file mode 100644 index aa51ab516..000000000 --- a/cmake/sync_generated.cmake.in +++ /dev/null @@ -1,83 +0,0 @@ -# Inherit the parent CMake setting -set(CURRENT_SOURCE_DIR @CMAKE_CURRENT_SOURCE_DIR@) -set(CURRENT_BINARY_DIR @CMAKE_CURRENT_BINARY_DIR@) -set(CACHED_FILES_DIR @CACHED_FILES_DIR@) -set(LEMON_EXECUTABLE @LEMON_EXECUTABLE@) -set(RE2C_EXECUTABLE @RE2C_EXECUTABLE@) -set(PERPLEX_EXECUTABLE @PERPLEX_EXECUTABLE@) -set(LOCKED_SOURCE_DIR @LOCKED_SOURCE_DIR@) -set(DEBUGGING_GENERATED_SOURCES @DEBUGGING_GENERATED_SOURCES@) - -if(NOT DEBUGGING_GENERATED_SOURCES) - # Define a variety of convenience routines - include(@PROJECT_CMAKE_DIR@/Generated_Source_Utils.cmake) - - # The following steps are executed to sync generated sources: - # - # 1. Create a new verification_info.cmake file and populate - # it with the current versions of perplex, re2c and lemon. - # Also add the MD5 sums for current template files. - # - # 2. For all files that need to be updated in the cache, - # calculate new MD5 sums and add them to the new - # verification_info.cmake - this is usually the input - # files and the generated outputs. - # - # 3. Overwrite the original cached verification_info.cmake - # and generated files with the new ones. If LOCKED_SOURCE_DIR - # is ON, this step will not be carried out - instead, an - # informational message with manual updating instructions - # will be printed. - - set(new_info_file "${CURRENT_BINARY_DIR}/verification_info.cmake.new") - - - file(WRITE ${new_info_file} "# Autogenerated verification information\n") - - # Handle generator version numbers - GET_GENERATOR_EXEC_VERSIONS() - file(APPEND ${new_info_file} "set(baseline_lemon_version \"${lemon_version}\")\n") - file(APPEND ${new_info_file} "set(baseline_re2c_version \"${re2c_version}\")\n") - file(APPEND ${new_info_file} "set(baseline_perplex_version \"${perplex_version}\")\n") - - # Handle template files - set(template_files "@TEMPLATE_FILELIST@") - WRITE_MD5_SUMS("${template_files}" "${new_info_file}") - - # Handle input files - set(input_files "@INPUT_FILELIST@") - WRITE_MD5_SUMS("${input_files}" "${new_info_file}") - - # Handle generated files - set(output_files "@BUILD_OUTPUT_FILELIST@") - WRITE_MD5_SUMS("${output_files}" "${new_info_file}") - - # Copy files into their final locations - if(NOT LOCKED_SOURCE_DIR) - configure_file(${new_info_file} "${CACHED_FILES_DIR}/verification_info.cmake" COPYONLY) - foreach(outf ${output_files}) - get_filename_component(filecorename ${outf} NAME) - message("copying ${outf} to ${CACHED_FILES_DIR}/${filecorename}") - configure_file(${outf} "${CACHED_FILES_DIR}/${filecorename}" COPYONLY) - endforeach(outf ${output_files}) - else(NOT LOCKED_SOURCE_DIR) - message("Source directory writing is locked - LOCKED_SOURCE_DIR is set.") - message("To update the generated files, manually copy the following to ${CACHED_FILES_DIR}:") - message(" ${new_info_file} (rename to verification_info.cmake)") - foreach(outf ${output_files}) - message(" ${outf}") - endforeach(outf ${output_files}) - endif(NOT LOCKED_SOURCE_DIR) - -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) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 4e99f0b70..e6ef03d19 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -10,7 +10,7 @@ # .exp file inside, which it uses. otherwise, ${path} is assumed to # be an express file. -if(NOT "${SC_BUILD_SCHEMAS}" STREQUAL "") +if(NOT "${SC_BUILD_EXPRESS_ONLY}" AND 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) @@ -25,7 +25,7 @@ if(NOT "${SC_BUILD_SCHEMAS}" STREQUAL "") LOCATE_SCHEMA(${FILE} abspath) SCHEMA_CMLIST(${abspath}) endforeach() -endif(NOT "${SC_BUILD_SCHEMAS}" STREQUAL "") +endif() # Local Variables: # tab-width: 8 diff --git a/data/ap238/ap238-aim-long.exp b/data/ap238/ap238-aim-long.exp index 2cc3248b2..3ed2f2d1a 100644 --- a/data/ap238/ap238-aim-long.exp +++ b/data/ap238/ap238-aim-long.exp @@ -3891,11 +3891,11 @@ ENTITY grooving_turning_operation WR3: (verify_optional_action_property (SELF, 'allowance')) AND (verify_length_measure_action_property (SELF, 'allowance')); - -- allowance propery required for roughing + -- allowance property required for roughing WR4: NOT (SELF.description = 'roughing') OR (verify_required_action_property (SELF, 'allowance')); - -- allowance propery forbidden for cutting in + -- allowance property forbidden for cutting in WR5: NOT (SELF.description = 'cutting in') OR (0 = SIZEOF (get_action_property (SELF, 'allowance'))); END_ENTITY; -- 10303-238: integrated_cnc_schema diff --git a/doc/doxyassist.xml b/doc/doxyassist.xml index 27db20f0c..3eb5f8ac3 100644 --- a/doc/doxyassist.xml +++ b/doc/doxyassist.xml @@ -36,7 +36,7 @@ English - diff --git a/doc/man/man1/exp2cxx.1 b/doc/man/man1/exp2cxx.1 index 8cb0514d7..7ff17dd3a 100644 --- a/doc/man/man1/exp2cxx.1 +++ b/doc/man/man1/exp2cxx.1 @@ -5,7 +5,7 @@ .\" $Id: exp2cxx.1,v 2.1.0.2 1998/02/27 23:54:30 sauderd Exp $ .TH FEDEX_PLUS 1 "19 November 1997" .SH NAME -exp2cxx - EXPRESS compiler and translater +exp2cxx - EXPRESS compiler and translator .SH SYNOPSIS exp2cxx [ options ] [ express-file ] .nf diff --git a/example/ap203min/CMakeLists.txt b/example/ap203min/CMakeLists.txt index 3765fa48a..5aea13a4b 100644 --- a/example/ap203min/CMakeLists.txt +++ b/example/ap203min/CMakeLists.txt @@ -6,7 +6,7 @@ # for the use of this file. # project(AP203Minimum) -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.12) # Set STEPCODE_ROOT_DIR to point to the root of the STEPcode source tree. if(NOT DEFINED STEPCODE_ROOT_DIR) @@ -14,14 +14,14 @@ if(NOT DEFINED STEPCODE_ROOT_DIR) 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") +if(EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/src/express/express.c") 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") + if(NOT EXISTS "${STEPCODE_ROOT_DIR}/src/express/express.c") 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") + endif(NOT EXISTS "${STEPCODE_ROOT_DIR}/src/express/express.c") +endif(EXISTS "${CMAKE_BINARY_DIR}/${STEPCODE_ROOT_DIR}/src/express/express.c") # Use STEPcode as library, but build from this build process. @@ -51,18 +51,13 @@ 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}) +set(STEPCODE_LIBRARIES stepcore stepeditor stepdai steputils ${SCHEMA_LINK_NAME}) # Add STEPCode project to CMake build. 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} diff --git a/example/ap203min/ExternalProjectBuild/CMakeLists.txt b/example/ap203min/ExternalProjectBuild/CMakeLists.txt index c73d648a2..45cce97e9 100644 --- a/example/ap203min/ExternalProjectBuild/CMakeLists.txt +++ b/example/ap203min/ExternalProjectBuild/CMakeLists.txt @@ -6,7 +6,7 @@ # for the use of this file. # project(AP203Minimum) -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.12) INCLUDE( ExternalProject ) @@ -19,7 +19,6 @@ INCLUDE( External_STEPCode ) IF(NOT WIN32) set( STEPCODE_LIBRARIES - ${STEPCODE_INSTALL_DIR}/lib/libbase.a ${STEPCODE_INSTALL_DIR}/lib/libstepcore.a ${STEPCODE_INSTALL_DIR}/lib/libstepeditor.a ${STEPCODE_INSTALL_DIR}/lib/libstepdai.a @@ -28,7 +27,6 @@ IF(NOT WIN32) ) ELSE() set( STEPCODE_LIBRARIES - ${STEPCODE_INSTALL_DIR}/lib/libbase.lib ${STEPCODE_INSTALL_DIR}/lib/libstepcore.lib ${STEPCODE_INSTALL_DIR}/lib/libstepeditor.lib ${STEPCODE_INSTALL_DIR}/lib/libstepdai.lib @@ -44,7 +42,6 @@ MESSAGE( STATUS "STEPCODE_INSTALL_DIR: " ${STEPCODE_INSTALL_DIR} ) set( STEPCODE_INCLUDE_DIR ${STEPCODE_INSTALL_DIR}/include/stepcode -${STEPCODE_INSTALL_DIR}/include/stepcode/base ${STEPCODE_INSTALL_DIR}/include/stepcode/clstepcore ${STEPCODE_INSTALL_DIR}/include/stepcode/cldai ${STEPCODE_INSTALL_DIR}/include/stepcode/clutils @@ -77,4 +74,4 @@ target_link_libraries( ${PROJECT_NAME} # mode: cmake # indent-tabs-mode: t # End: -# ex: shiftwidth=2 tabstop=8 \ No newline at end of file +# ex: shiftwidth=2 tabstop=8 diff --git a/example/ap203min/ExternalProjectBuild/cmake/External_STEPCode.cmake b/example/ap203min/ExternalProjectBuild/cmake/External_STEPCode.cmake index 62df14322..96fca295b 100644 --- a/example/ap203min/ExternalProjectBuild/cmake/External_STEPCode.cmake +++ b/example/ap203min/ExternalProjectBuild/cmake/External_STEPCode.cmake @@ -22,8 +22,3 @@ ENDIF() SET( STEPCODE_BINARY_DIR ${BINARY_DIR} ) -# SC CMake does not honor -DCMAKE_INSTALL_PREFIX:PATH= -# Consequently, force Debug so it installs in ../sc-install directory -# instead of /usr/local/lib. -# -# SC's own programs fail to build with -DSC_BUILD_SHARED_LIBS=OFF \ No newline at end of file diff --git a/example/ap203min/ap203min.cpp b/example/ap203min/ap203min.cpp index 5e05b7b59..1a6039f83 100644 --- a/example/ap203min/ap203min.cpp +++ b/example/ap203min/ap203min.cpp @@ -49,15 +49,15 @@ // $./AP203Minimum // AP203Minimum outfile.stp -#include -#include -#include -#include -#include -#include - -#include -#include +#include +#include +#include +#include +#include +#include + +#include +#include #include "schema.h" diff --git a/include/sc_cf_cmake.h.in b/example/ap203min/include/config.h.in similarity index 86% rename from include/sc_cf_cmake.h.in rename to example/ap203min/include/config.h.in index 3d744d15d..63ccc4ed1 100644 --- a/include/sc_cf_cmake.h.in +++ b/example/ap203min/include/config.h.in @@ -2,8 +2,9 @@ #define SCL_CF_H /**** Define statements for CMake ****/ +#cmakedefine SC_VERSION "@SC_VERSION@" #cmakedefine HAVE_NDIR_H 1 -#cmakedefine HAVE_STDARG_H 1 +#cmakedefine HAVE_STDINT_H 1 #cmakedefine HAVE_SYS_STAT_H 1 #cmakedefine HAVE_SYS_PARAM_H 1 #cmakedefine HAVE_SYSENT_H 1 @@ -14,12 +15,12 @@ #cmakedefine HAVE_IO_H 1 #cmakedefine SC_TRACE_FPRINTF 1 -#cmakedefine SC_MEMMGR_ENABLE_CHECKS 1 #cmakedefine HAVE_ABS 1 #cmakedefine HAVE_MEMCPY 1 #cmakedefine HAVE_MEMMOVE 1 #cmakedefine HAVE_GETOPT 1 +#cmakedefine HAVE_VSNPRINTF 1 #cmakedefine HAVE_SSIZE_T 1 diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 566c3780d..5f39f0ba9 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -22,22 +22,26 @@ set(express_HDRS express/variable.h ) install(FILES ${express_HDRS} - DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/express) + DESTINATION ${INCLUDE_DIR}/stepcode/express) set(exppp_HDRS exppp/exppp.h ) install(FILES ${exppp_HDRS} - DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/exppp) + DESTINATION ${INCLUDE_DIR}/stepcode/exppp) install(FILES ordered_attrs.h sc_export.h - sc_stdbool.h - DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode) + DESTINATION ${INCLUDE_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) +install(FILES ${SC_BINARY_DIR}/${INCLUDE_DIR}/config.h + DESTINATION ${INCLUDE_DIR}/stepcode) + +add_subdirectory(cldai) +add_subdirectory(cleditor) +add_subdirectory(cllazyfile) +add_subdirectory(clstepcore) +add_subdirectory(clutils) # Local Variables: # tab-width: 8 diff --git a/include/cldai/CMakeLists.txt b/include/cldai/CMakeLists.txt new file mode 100644 index 000000000..471671fbd --- /dev/null +++ b/include/cldai/CMakeLists.txt @@ -0,0 +1,24 @@ +set(DAI_HDRS + sdaiApplication_instance_set.h + sdaiBinary.h + sdaiDaObject.h + sdaiEntity_extent.h + sdaiEntity_extent_set.h + sdaiEnum.h + sdaiModel_contents.h + sdaiModel_contents_list.h + sdaiObject.h + sdaiSession_instance.h + sdaiString.h + ) + +install(FILES ${DAI_HDRS} + DESTINATION ${INCLUDE_DIR}/stepcode/cldai) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 + diff --git a/src/cldai/sdaiApplication_instance_set.h b/include/cldai/sdaiApplication_instance_set.h similarity index 100% rename from src/cldai/sdaiApplication_instance_set.h rename to include/cldai/sdaiApplication_instance_set.h diff --git a/src/cldai/sdaiBinary.h b/include/cldai/sdaiBinary.h similarity index 93% rename from src/cldai/sdaiBinary.h rename to include/cldai/sdaiBinary.h index 151863ea0..76bb56d18 100644 --- a/src/cldai/sdaiBinary.h +++ b/include/cldai/sdaiBinary.h @@ -15,7 +15,15 @@ class SC_DAI_EXPORT SDAI_Binary { private: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string content; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + public: //constructor(s) & destructor diff --git a/src/cldai/sdaiDaObject.h b/include/cldai/sdaiDaObject.h similarity index 99% rename from src/cldai/sdaiDaObject.h rename to include/cldai/sdaiDaObject.h index 29ddc4e5d..3bb0c20f4 100644 --- a/src/cldai/sdaiDaObject.h +++ b/include/cldai/sdaiDaObject.h @@ -1,9 +1,9 @@ #ifndef SDAIDAOBJECT_H #define SDAIDAOBJECT_H 1 -#include -#include -#include +#include "cldai/sdaiObject.h" +#include "cldai/sdaiString.h" +#include "cldai/sdaiEnum.h" #include @@ -65,7 +65,7 @@ typedef SDAI_PID_ptr SDAI_PID_var; // The Direct Access Protocol supports direct access to persistent data // through typed attributes organized in data objects that are defined // in a Data Definition Language (DDL). An object using this protocol -// whould represent its persistent data as one or more interconnected +// would represent its persistent data as one or more interconnected // data objects, For uniformity, the persistent data of an object is // described as a single data object; however, that data object might be // the root of a graph of data objects interconnected by stored data diff --git a/src/cldai/sdaiEntity_extent.h b/include/cldai/sdaiEntity_extent.h similarity index 98% rename from src/cldai/sdaiEntity_extent.h rename to include/cldai/sdaiEntity_extent.h index 0dcca471f..68c90c2b5 100644 --- a/src/cldai/sdaiEntity_extent.h +++ b/include/cldai/sdaiEntity_extent.h @@ -56,7 +56,7 @@ class SC_DAI_EXPORT SDAI_Entity_extent : public SDAI_Session_instance { return &_instances; } SDAI_DAObject__set_var instances_() const { - return ( const SDAI_DAObject__set_var )&_instances; + return ( SDAI_DAObject__set_var )&_instances; } // need to implement Model_contents__list diff --git a/src/cldai/sdaiEntity_extent_set.h b/include/cldai/sdaiEntity_extent_set.h similarity index 100% rename from src/cldai/sdaiEntity_extent_set.h rename to include/cldai/sdaiEntity_extent_set.h diff --git a/src/cldai/sdaiEnum.h b/include/cldai/sdaiEnum.h similarity index 98% rename from src/cldai/sdaiEnum.h rename to include/cldai/sdaiEnum.h index c883f2be6..aff524b88 100644 --- a/src/cldai/sdaiEnum.h +++ b/include/cldai/sdaiEnum.h @@ -138,6 +138,7 @@ class SC_DAI_EXPORT SDAI_BOOLEAN : operator ::Boolean() const; SDAI_BOOLEAN & operator=( const SDAI_LOGICAL & t ); + SDAI_BOOLEAN & operator=( const SDAI_BOOLEAN & t ); SDAI_BOOLEAN & operator=( const ::Boolean t ); SDAI_LOGICAL operator==( const SDAI_LOGICAL & t ) const; diff --git a/src/cldai/sdaiModel_contents.h b/include/cldai/sdaiModel_contents.h similarity index 99% rename from src/cldai/sdaiModel_contents.h rename to include/cldai/sdaiModel_contents.h index 5795232dc..984742728 100644 --- a/src/cldai/sdaiModel_contents.h +++ b/include/cldai/sdaiModel_contents.h @@ -40,7 +40,7 @@ class SC_DAI_EXPORT SDAI_Model_contents_instances : public SDAI_DAObject { return &_instances; } SDAI_DAObject__set_var contents_() const { - return ( const SDAI_DAObject__set_var ) &_instances; + return ( SDAI_DAObject__set_var ) &_instances; } }; diff --git a/src/cldai/sdaiModel_contents_list.h b/include/cldai/sdaiModel_contents_list.h similarity index 100% rename from src/cldai/sdaiModel_contents_list.h rename to include/cldai/sdaiModel_contents_list.h diff --git a/src/cldai/sdaiObject.h b/include/cldai/sdaiObject.h similarity index 100% rename from src/cldai/sdaiObject.h rename to include/cldai/sdaiObject.h diff --git a/src/cldai/sdaiSession_instance.h b/include/cldai/sdaiSession_instance.h similarity index 94% rename from src/cldai/sdaiSession_instance.h rename to include/cldai/sdaiSession_instance.h index fcc8fad15..7aa9a1502 100644 --- a/src/cldai/sdaiSession_instance.h +++ b/include/cldai/sdaiSession_instance.h @@ -3,7 +3,7 @@ #define SESSION_INSTANCE_H 1 #include -//#include +//#include "clstepcore/sdai.h" class SC_DAI_EXPORT SDAI_Session_instance : public SDAI_sdaiObject { diff --git a/src/cldai/sdaiString.h b/include/cldai/sdaiString.h similarity index 86% rename from src/cldai/sdaiString.h rename to include/cldai/sdaiString.h index e365e575d..7fd40e1cf 100644 --- a/src/cldai/sdaiString.h +++ b/include/cldai/sdaiString.h @@ -12,12 +12,21 @@ */ #include +#include #include class SC_DAI_EXPORT SDAI_String { private: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string content; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + public: //constructor(s) & destructor @@ -28,6 +37,7 @@ class SC_DAI_EXPORT SDAI_String { // operators SDAI_String & operator= ( const char * s ); + SDAI_String & operator= ( const SDAI_String & s ); bool operator== ( const char * s ) const; void clear( void ); diff --git a/include/cleditor/CMakeLists.txt b/include/cleditor/CMakeLists.txt new file mode 100644 index 000000000..1d128c8fa --- /dev/null +++ b/include/cleditor/CMakeLists.txt @@ -0,0 +1,20 @@ +set(EDITOR_HDRS + STEPfile.h + cmdmgr.h + editordefines.h + SdaiHeaderSchema.h + SdaiHeaderSchemaClasses.h + SdaiSchemaInit.h + seeinfodefault.h + ) + +install(FILES ${EDITOR_HDRS} + DESTINATION ${INCLUDE_DIR}/stepcode/cleditor) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 + diff --git a/src/cleditor/STEPfile.h b/include/cleditor/STEPfile.h similarity index 95% rename from src/cleditor/STEPfile.h rename to include/cleditor/STEPfile.h index 124795539..1ecfb67c2 100644 --- a/src/cleditor/STEPfile.h +++ b/include/cleditor/STEPfile.h @@ -15,14 +15,14 @@ #include #include -#include -#include +#include "clstepcore/instmgr.h" +#include "clstepcore/Registry.h" #include -#include -#include +#include "clutils/dirobj.h" +#include "clutils/errordesc.h" #include -#include +#include "clstepcore/read_func.h" //error reporting level #define READ_COMPLETE 10 @@ -58,11 +58,18 @@ class SC_EDITOR_EXPORT STEPfile { //file information DirObj * _currentDir; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string _fileName; //the following are used to compute read/write progress std::ifstream::pos_type _iFileSize; ///< input file size std::ifstream::pos_type _iFileCurrentPosition; ///< input file position (from ifstream::tellg()) +#ifdef _MSC_VER +#pragma warning( pop ) +#endif bool _iFileStage1Done; ///< set immediately before ReadData1() returns int _oFileInstsWritten; ///< number of instances that have been written @@ -92,8 +99,15 @@ class SC_EDITOR_EXPORT STEPfile { //file type information FileTypeCode _fileType; char ENTITY_NAME_DELIM; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string FILE_DELIM; std::string END_FILE_DELIM; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif //public member functions public: diff --git a/src/cleditor/SdaiHeaderSchema.h b/include/cleditor/SdaiHeaderSchema.h similarity index 97% rename from src/cleditor/SdaiHeaderSchema.h rename to include/cleditor/SdaiHeaderSchema.h index 7cd45d848..5979202f0 100644 --- a/src/cleditor/SdaiHeaderSchema.h +++ b/include/cleditor/SdaiHeaderSchema.h @@ -5,11 +5,11 @@ // regenerate it. #include -#include -#include -#include -#include -#include +#include "clstepcore/sdai.h" +#include "clstepcore/Registry.h" +#include "clstepcore/STEPaggregate.h" +#include "cleditor/SdaiHeaderSchemaClasses.h" +#include "cleditor/SdaiSchemaInit.h" ///////// ENTITY section_language diff --git a/src/cleditor/SdaiHeaderSchemaClasses.h b/include/cleditor/SdaiHeaderSchemaClasses.h similarity index 100% rename from src/cleditor/SdaiHeaderSchemaClasses.h rename to include/cleditor/SdaiHeaderSchemaClasses.h diff --git a/src/cleditor/SdaiSchemaInit.h b/include/cleditor/SdaiSchemaInit.h similarity index 60% rename from src/cleditor/SdaiSchemaInit.h rename to include/cleditor/SdaiSchemaInit.h index a0868fbc6..862f297bd 100644 --- a/src/cleditor/SdaiSchemaInit.h +++ b/include/cleditor/SdaiSchemaInit.h @@ -9,16 +9,16 @@ #endif #include -#include -#include -#include -#include -#include -#include -#include +#include "clstepcore/sdai.h" +#include "clstepcore/Registry.h" +#include "clstepcore/STEPaggregate.h" +#include "clstepcore/STEPundefined.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/complexSupport.h" -#include -#include +#include "cleditor/SdaiHeaderSchemaClasses.h" +#include "cleditor/SdaiHeaderSchema.h" SC_EDITOR_EXPORT void HeaderSchemaInit( Registry & ); SC_EDITOR_EXPORT void HeaderInitSchemasAndEnts( Registry & ); diff --git a/src/cleditor/cmdmgr.h b/include/cleditor/cmdmgr.h similarity index 94% rename from src/cleditor/cmdmgr.h rename to include/cleditor/cmdmgr.h index 7ef2f00b5..4f420467b 100644 --- a/src/cleditor/cmdmgr.h +++ b/include/cleditor/cmdmgr.h @@ -13,16 +13,16 @@ */ #include -#include -#include -#include +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" +#include "clutils/gennodearray.h" -#include -#include -#include -#include -#include -#include +#include "cleditor/editordefines.h" +#include "clstepcore/mgrnode.h" +#include "clstepcore/mgrnodelist.h" +#include "clstepcore/dispnode.h" +#include "clstepcore/dispnodelist.h" +#include "clstepcore/SingleLinkList.h" //#define NUM_CMDMGR_CMDS 9 // this is the number of columns that contain cmds (as opposed @@ -145,6 +145,7 @@ class SC_EDITOR_EXPORT CmdMgr { public: CmdMgr(); + ~CmdMgr(); // STATE LIST OPERATIONS MgrNode * GetHead( stateEnum listType ); diff --git a/src/cleditor/editordefines.h b/include/cleditor/editordefines.h similarity index 100% rename from src/cleditor/editordefines.h rename to include/cleditor/editordefines.h diff --git a/src/cleditor/seeinfodefault.h b/include/cleditor/seeinfodefault.h similarity index 94% rename from src/cleditor/seeinfodefault.h rename to include/cleditor/seeinfodefault.h index 51198eac8..202c5eb1a 100644 --- a/src/cleditor/seeinfodefault.h +++ b/include/cleditor/seeinfodefault.h @@ -20,10 +20,10 @@ class MgrNode; class DisplayNode; class DisplayNodelist; -#include +#include "clstepcore/sdai.h" //class SDAI_Application_instance; -#include +#include "cleditor/editordefines.h" class SC_EDITOR_EXPORT seeInfo : public DisplayNode { public: diff --git a/include/cllazyfile/CMakeLists.txt b/include/cllazyfile/CMakeLists.txt new file mode 100644 index 000000000..853aa98b9 --- /dev/null +++ b/include/cllazyfile/CMakeLists.txt @@ -0,0 +1,27 @@ +set(LAZY_HDRS + headerSectionReader.h + lazyFileReader.h + lazyP21DataSectionReader.h + p21HeaderSectionReader.h + lazyDataSectionReader.h + lazyInstMgr.h + lazyTypes.h + sectionReader.h + instMgrHelper.h + judy.h + judyL2Array.h + judyLArray.h + judyS2Array.h + judySArray.h + ) + +install(FILES ${LAZY_HDRS} + DESTINATION ${INCLUDE_DIR}/stepcode/cllazyfile) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 + diff --git a/src/cllazyfile/headerSectionReader.h b/include/cllazyfile/headerSectionReader.h similarity index 88% rename from src/cllazyfile/headerSectionReader.h rename to include/cllazyfile/headerSectionReader.h index 8a51f5721..e3a9f5725 100644 --- a/src/cllazyfile/headerSectionReader.h +++ b/include/cllazyfile/headerSectionReader.h @@ -5,10 +5,9 @@ #include #include "judyL2Array.h" -#include "lazyFileReader.h" -#include "sectionReader.h" -#include "lazyTypes.h" -#include "sc_memmgr.h" +#include "cllazyfile/lazyFileReader.h" +#include "cllazyfile/sectionReader.h" +#include "cllazyfile/lazyTypes.h" #include "sc_export.h" @@ -31,6 +30,7 @@ class SC_LAZYFILE_EXPORT headerSectionReader: public sectionReader { //FIXME delete each instance?! maybe add to clear, since it iterates over everything already //enum clearHow { rawData, deletePointers } _headerInstances->clear(); + delete _headerInstances; } }; diff --git a/src/cllazyfile/instMgrHelper.h b/include/cllazyfile/instMgrHelper.h similarity index 94% rename from src/cllazyfile/instMgrHelper.h rename to include/cllazyfile/instMgrHelper.h index 659f1ec8e..1af698160 100644 --- a/src/cllazyfile/instMgrHelper.h +++ b/include/cllazyfile/instMgrHelper.h @@ -3,9 +3,9 @@ #include -#include -#include -#include +#include "clstepcore/mgrnode.h" +#include "cllazyfile/lazyInstMgr.h" +#include "clstepcore/instmgr.h" /** * \file instMgrHelper.h helper classes for the lazyInstMgr. Allows use of SDAI_Application_instance class diff --git a/src/base/judy/src/judy.h b/include/cllazyfile/judy.h similarity index 93% rename from src/base/judy/src/judy.h rename to include/cllazyfile/judy.h index 8721fc293..dfd193cf3 100644 --- a/src/base/judy/src/judy.h +++ b/include/cllazyfile/judy.h @@ -32,18 +32,7 @@ // judy_prv: retrieve the cell pointer for the prev string in the array. // judy_del: delete the key and cell for the current stack entry. -/* Import/Export flags for base. */ -#ifndef SC_BASE_EXPORT -# if defined(SC_BASE_DLL_EXPORTS) && defined(SC_BASE_DLL_IMPORTS) -# error "Only SC_BASE_DLL_EXPORTS or SC_BASE_DLL_IMPORTS can be defined, not both." -# elif defined(SC_BASE_DLL_EXPORTS) -# define SC_BASE_EXPORT __declspec(dllexport) -# elif defined(SC_BASE_DLL_IMPORTS) -# define SC_BASE_EXPORT __declspec(dllimport) -# else -# define SC_BASE_EXPORT -# endif -#endif +#include "sc_export.h" #if defined(__LP64__) || \ defined(__x86_64__) || \ diff --git a/src/base/judy/src/judyL2Array.h b/include/cllazyfile/judyL2Array.h similarity index 100% rename from src/base/judy/src/judyL2Array.h rename to include/cllazyfile/judyL2Array.h diff --git a/src/base/judy/src/judyLArray.h b/include/cllazyfile/judyLArray.h similarity index 100% rename from src/base/judy/src/judyLArray.h rename to include/cllazyfile/judyLArray.h diff --git a/src/base/judy/src/judyS2Array.h b/include/cllazyfile/judyS2Array.h similarity index 100% rename from src/base/judy/src/judyS2Array.h rename to include/cllazyfile/judyS2Array.h diff --git a/src/base/judy/src/judySArray.h b/include/cllazyfile/judySArray.h similarity index 100% rename from src/base/judy/src/judySArray.h rename to include/cllazyfile/judySArray.h diff --git a/src/cllazyfile/lazyDataSectionReader.h b/include/cllazyfile/lazyDataSectionReader.h similarity index 79% rename from src/cllazyfile/lazyDataSectionReader.h rename to include/cllazyfile/lazyDataSectionReader.h index 8cd4b0468..6fad4e0b8 100644 --- a/src/cllazyfile/lazyDataSectionReader.h +++ b/include/cllazyfile/lazyDataSectionReader.h @@ -3,9 +3,8 @@ #include #include -#include "sectionReader.h" -#include "lazyTypes.h" -#include "sc_memmgr.h" +#include "cllazyfile/sectionReader.h" +#include "cllazyfile/lazyTypes.h" #include "sc_export.h" @@ -16,7 +15,14 @@ class SC_LAZYFILE_EXPORT lazyDataSectionReader: public sectionReader { protected: bool _error, _completelyLoaded; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string _sectionIdentifier; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif /// only makes sense to call the ctor from derived class ctors lazyDataSectionReader( lazyFileReader * parent, std::ifstream & file, std::streampos start, sectionID sid ); diff --git a/src/cllazyfile/lazyFileReader.h b/include/cllazyfile/lazyFileReader.h similarity index 82% rename from src/cllazyfile/lazyFileReader.h rename to include/cllazyfile/lazyFileReader.h index 44def9fb4..9a5fccb5e 100644 --- a/src/cllazyfile/lazyFileReader.h +++ b/include/cllazyfile/lazyFileReader.h @@ -8,16 +8,14 @@ #include "sc_export.h" // PART 21 -#include "lazyP21DataSectionReader.h" -#include "p21HeaderSectionReader.h" -#include "headerSectionReader.h" +#include "cllazyfile/lazyP21DataSectionReader.h" +#include "cllazyfile/p21HeaderSectionReader.h" +#include "cllazyfile/headerSectionReader.h" /* // PART 28 * #include "lazyP28DataSectionReader.h" * #include "p28HeaderSectionReader.h" */ -#include "sc_memmgr.h" - class lazyInstMgr; class Registry; class headerSectionReader; @@ -26,10 +24,17 @@ class headerSectionReader; ///for use only from within lazyInstMgr class SC_LAZYFILE_EXPORT lazyFileReader { protected: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string _fileName; lazyInstMgr * _parent; headerSectionReader * _header; std::ifstream _file; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif fileTypeEnum _fileType; fileID _fileID; diff --git a/src/cllazyfile/lazyInstMgr.h b/include/cllazyfile/lazyInstMgr.h similarity index 96% rename from src/cllazyfile/lazyInstMgr.h rename to include/cllazyfile/lazyInstMgr.h index 3a7e682ce..e3445660a 100644 --- a/src/cllazyfile/lazyInstMgr.h +++ b/include/cllazyfile/lazyInstMgr.h @@ -5,12 +5,11 @@ #include #include -#include "lazyDataSectionReader.h" -#include "lazyFileReader.h" -#include "lazyTypes.h" +#include "cllazyfile/lazyDataSectionReader.h" +#include "cllazyfile/lazyFileReader.h" +#include "cllazyfile/lazyTypes.h" -#include "Registry.h" -#include "sc_memmgr.h" +#include "clstepcore/Registry.h" #include "sc_export.h" #include "judyLArray.h" @@ -26,6 +25,10 @@ class SC_LAZYFILE_EXPORT lazyInstMgr { /** multimap from instance number to instances that it refers to * \sa instanceRefs_pair */ +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif instanceRefs_t _fwdInstanceRefs; /** multimap from instance number to instances that refer to it - the majority of these will not be inverse references! * \sa instanceRefs_pair @@ -67,6 +70,10 @@ class SC_LAZYFILE_EXPORT lazyInstMgr { instMgrAdapter * _ima; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + public: lazyInstMgr(); ~lazyInstMgr(); diff --git a/src/cllazyfile/lazyP21DataSectionReader.h b/include/cllazyfile/lazyP21DataSectionReader.h similarity index 89% rename from src/cllazyfile/lazyP21DataSectionReader.h rename to include/cllazyfile/lazyP21DataSectionReader.h index 423679142..c14376fc0 100644 --- a/src/cllazyfile/lazyP21DataSectionReader.h +++ b/include/cllazyfile/lazyP21DataSectionReader.h @@ -1,9 +1,8 @@ #ifndef LAZYP21DATASECTIONREADER_H #define LAZYP21DATASECTIONREADER_H -#include "lazyDataSectionReader.h" -#include "lazyFileReader.h" -#include "sc_memmgr.h" +#include "cllazyfile/lazyDataSectionReader.h" +#include "cllazyfile/lazyFileReader.h" #include "sc_export.h" class SC_LAZYFILE_EXPORT lazyP21DataSectionReader: public lazyDataSectionReader { diff --git a/src/cllazyfile/lazyTypes.h b/include/cllazyfile/lazyTypes.h similarity index 94% rename from src/cllazyfile/lazyTypes.h rename to include/cllazyfile/lazyTypes.h index 28b7ac60c..f1fdbd782 100644 --- a/src/cllazyfile/lazyTypes.h +++ b/include/cllazyfile/lazyTypes.h @@ -1,10 +1,20 @@ #ifndef LAZYTYPES_H #define LAZYTYPES_H +#include "config.h" + #include #include #include + +#ifdef HAVE_STDINT_H #include +#else +#if defined(_MSC_VER) && _MSC_VER < 1600 +typedef unsigned __int64 uint64_t; +typedef unsigned __int16 uint16_t; +#endif +#endif #include "judyLArray.h" #include "judySArray.h" diff --git a/src/cllazyfile/p21HeaderSectionReader.h b/include/cllazyfile/p21HeaderSectionReader.h similarity index 91% rename from src/cllazyfile/p21HeaderSectionReader.h rename to include/cllazyfile/p21HeaderSectionReader.h index b5ce04948..ab91fb2bd 100644 --- a/src/cllazyfile/p21HeaderSectionReader.h +++ b/include/cllazyfile/p21HeaderSectionReader.h @@ -1,8 +1,7 @@ #ifndef P21HEADERSECTIONREADER_H #define P21HEADERSECTIONREADER_H -#include "headerSectionReader.h" -#include "sc_memmgr.h" +#include "cllazyfile/headerSectionReader.h" #include "sc_export.h" class SC_LAZYFILE_EXPORT p21HeaderSectionReader: public headerSectionReader { diff --git a/src/cllazyfile/sectionReader.h b/include/cllazyfile/sectionReader.h similarity index 93% rename from src/cllazyfile/sectionReader.h rename to include/cllazyfile/sectionReader.h index 8af3efd6b..74f1fa5bf 100644 --- a/src/cllazyfile/sectionReader.h +++ b/include/cllazyfile/sectionReader.h @@ -3,11 +3,10 @@ #include #include -#include "lazyTypes.h" -#include "sc_memmgr.h" +#include "cllazyfile/lazyTypes.h" #include "sc_export.h" -#include "errordesc.h" -#include "STEPcomplex.h" +#include "clutils/errordesc.h" +#include "clstepcore/STEPcomplex.h" class SDAI_Application_instance; class lazyFileReader; @@ -18,10 +17,17 @@ class SC_LAZYFILE_EXPORT sectionReader { protected: //protected data members lazyFileReader * _lazyFile; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::ifstream & _file; std::streampos _sectionStart, ///< the start of this section as reported by tellg() _sectionEnd; ///< the end of this section as reported by tellg() +#ifdef _MSC_VER +#pragma warning( pop ) +#endif unsigned long _totalInstances; ErrorDescriptor * _error; @@ -31,6 +37,7 @@ class SC_LAZYFILE_EXPORT sectionReader { // protected member functions sectionReader( lazyFileReader * parent, std::ifstream & file, std::streampos start, sectionID sid ); + ~sectionReader(); /** Find a string, ignoring occurrences in comments or Part 21 strings (i.e. 'string with \S\' control directive' ) * \param str string to find diff --git a/include/clstepcore/CMakeLists.txt b/include/clstepcore/CMakeLists.txt new file mode 100644 index 000000000..a8447cea3 --- /dev/null +++ b/include/clstepcore/CMakeLists.txt @@ -0,0 +1,71 @@ +set(CORE_HDRS + aggrTypeDescriptor.h + attrDescriptor.h + attrDescriptorList.h + baseType.h + complexSupport.h + create_Aggr.h + derivedAttribute.h + dictSchema.h + dictdefs.h + dictionaryInstance.h + dispnode.h + dispnodelist.h + entityDescriptor.h + entityDescriptorList.h + enumTypeDescriptor.h + ExpDict.h + explicitItemId.h + globalRule.h + implicitItemId.h + instmgr.h + interfaceSpec.h + interfacedItem.h + inverseAttribute.h + inverseAttributeList.h + mgrnode.h + mgrnodearray.h + mgrnodelist.h + needFunc.h + read_func.h + realTypeDescriptor.h + Registry.h + schRename.h + sdai.h + sdaiApplication_instance.h + sdaiSelect.h + selectTypeDescriptor.h + SingleLinkList.h + STEPaggregate.h + STEPaggrBinary.h + STEPaggrEntity.h + STEPaggrEnum.h + STEPaggrGeneric.h + STEPaggrInt.h + STEPaggrReal.h + STEPaggrSelect.h + STEPaggrString.h + STEPattribute.h + STEPattributeList.h + STEPcomplex.h + STEPinvAttrList.h + STEPundefined.h + stringTypeDescriptor.h + SubSuperIterators.h + typeDescriptor.h + typeDescriptorList.h + typeOrRuleVar.h + uniquenessRule.h + whereRule.h +) + +install(FILES ${CORE_HDRS} + DESTINATION ${INCLUDE_DIR}/stepcode/clstepcore) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 + diff --git a/src/clstepcore/ExpDict.h b/include/clstepcore/ExpDict.h similarity index 70% rename from src/clstepcore/ExpDict.h rename to include/clstepcore/ExpDict.h index e73b8dd01..c8c71258b 100644 --- a/src/clstepcore/ExpDict.h +++ b/include/clstepcore/ExpDict.h @@ -15,20 +15,20 @@ */ #include -#include +#include "clstepcore/sdai.h" #include #include #include -#include +#include "clstepcore/SingleLinkList.h" -#include -#include -#include +#include "clstepcore/baseType.h" +#include "clstepcore/dictdefs.h" +#include "clutils/Str.h" // each of these contains linked list, list node, iterator -#include "attrDescriptorList.h" +#include "clstepcore/attrDescriptorList.h" #include "inverseAttributeList.h" #include "typeDescriptorList.h" #include "entityDescriptorList.h" @@ -37,12 +37,12 @@ #include "typeDescriptor.h" #include "entityDescriptor.h" #include "enumTypeDescriptor.h" -#include "attrDescriptor.h" -#include "derivedAttribute.h" +#include "clstepcore/attrDescriptor.h" +#include "clstepcore/derivedAttribute.h" #include "inverseAttribute.h" -#include "create_Aggr.h" -#include "dictionaryInstance.h" +#include "clstepcore/create_Aggr.h" +#include "clstepcore/dictionaryInstance.h" #include "uniquenessRule.h" #include "whereRule.h" @@ -53,10 +53,10 @@ #include "interfaceSpec.h" #include "typeOrRuleVar.h" #include "globalRule.h" -#include "dictSchema.h" +#include "clstepcore/dictSchema.h" #include "schRename.h" -#include "aggrTypeDescriptor.h" +#include "clstepcore/aggrTypeDescriptor.h" #include "selectTypeDescriptor.h" #include "stringTypeDescriptor.h" #include "realTypeDescriptor.h" diff --git a/src/clstepcore/Registry.h b/include/clstepcore/Registry.h similarity index 95% rename from src/clstepcore/Registry.h rename to include/clstepcore/Registry.h index d4d4d4db0..099015686 100644 --- a/src/clstepcore/Registry.h +++ b/include/clstepcore/Registry.h @@ -13,11 +13,11 @@ */ #include -#include -#include -#include -#include -#include +#include "clstepcore/sdai.h" +#include "clutils/errordesc.h" +#include "clutils/sc_hash.h" +#include "clutils/Str.h" +#include "clstepcore/complexSupport.h" // defined and created in Registry.cc diff --git a/src/clstepcore/STEPaggrBinary.h b/include/clstepcore/STEPaggrBinary.h similarity index 97% rename from src/clstepcore/STEPaggrBinary.h rename to include/clstepcore/STEPaggrBinary.h index cd4991bbb..59ea61ab5 100644 --- a/src/clstepcore/STEPaggrBinary.h +++ b/include/clstepcore/STEPaggrBinary.h @@ -1,7 +1,7 @@ #ifndef STEPAGGRBINARY_H #define STEPAGGRBINARY_H -#include "STEPaggregate.h" +#include "clstepcore/STEPaggregate.h" #include /** \file STEPaggrBinary.h diff --git a/src/clstepcore/STEPaggrEntity.h b/include/clstepcore/STEPaggrEntity.h similarity index 97% rename from src/clstepcore/STEPaggrEntity.h rename to include/clstepcore/STEPaggrEntity.h index 76a0ec95c..8338fc8f8 100644 --- a/src/clstepcore/STEPaggrEntity.h +++ b/include/clstepcore/STEPaggrEntity.h @@ -5,7 +5,7 @@ * classes EntityAggregate, EntityNode */ -#include "STEPaggregate.h" +#include "clstepcore/STEPaggregate.h" #include class SC_CORE_EXPORT EntityAggregate : public STEPaggregate { @@ -57,7 +57,7 @@ class SC_CORE_EXPORT EntityNode : public STEPnode { virtual SingleLinkNode * NewNode(); - // Calling these funtions is an error. + // Calling these functions is an error. Severity StrToVal( const char * s, ErrorDescriptor * err ) { cerr << "Internal error: " << __FILE__ << __LINE__ << "\n" << _POC_ "\n"; diff --git a/src/clstepcore/STEPaggrEnum.h b/include/clstepcore/STEPaggrEnum.h similarity index 92% rename from src/clstepcore/STEPaggrEnum.h rename to include/clstepcore/STEPaggrEnum.h index 161706a48..cf16fb0e6 100644 --- a/src/clstepcore/STEPaggrEnum.h +++ b/include/clstepcore/STEPaggrEnum.h @@ -1,7 +1,7 @@ #ifndef STEPAGGRENUM_H #define STEPAGGRENUM_H -#include "STEPaggregate.h" +#include "clstepcore/STEPaggregate.h" #include "sc_export.h" /** \file StepaggrEnum.h * classes EnumAggregate, LOGICALS, BOOLEANS, EnumNode @@ -9,7 +9,7 @@ /** * \class EnumAggregate - * This is a minimal representions for a collection of SDAI_Enum + * This is a minimal representation for a collection of SDAI_Enum */ class SC_CORE_EXPORT EnumAggregate : public STEPaggregate { public: @@ -55,7 +55,7 @@ SC_CORE_EXPORT BOOLEANS * create_BOOLEANS(); /** * * \class EnumNode - ** This is a minimal representions for node in lists of SDAI_Enum + ** This is a minimal representation for node in lists of SDAI_Enum */ class SC_CORE_EXPORT EnumNode : public STEPnode { public: diff --git a/src/clstepcore/STEPaggrGeneric.h b/include/clstepcore/STEPaggrGeneric.h similarity index 97% rename from src/clstepcore/STEPaggrGeneric.h rename to include/clstepcore/STEPaggrGeneric.h index 76190406e..ecb286d00 100644 --- a/src/clstepcore/STEPaggrGeneric.h +++ b/include/clstepcore/STEPaggrGeneric.h @@ -1,7 +1,7 @@ #ifndef STEPAGGRGENERIC_H #define STEPAGGRGENERIC_H -#include "STEPaggregate.h" +#include "clstepcore/STEPaggregate.h" #include /** \file STEPaggrGeneric.h diff --git a/src/clstepcore/STEPaggrInt.h b/include/clstepcore/STEPaggrInt.h similarity index 97% rename from src/clstepcore/STEPaggrInt.h rename to include/clstepcore/STEPaggrInt.h index 726d07c0e..11bf57464 100644 --- a/src/clstepcore/STEPaggrInt.h +++ b/include/clstepcore/STEPaggrInt.h @@ -1,7 +1,7 @@ #ifndef STEPAGGRINT_H #define STEPAGGRINT_H -#include "STEPaggregate.h" +#include "clstepcore/STEPaggregate.h" #include class SC_CORE_EXPORT IntAggregate : public STEPaggregate { diff --git a/src/clstepcore/STEPaggrReal.h b/include/clstepcore/STEPaggrReal.h similarity index 97% rename from src/clstepcore/STEPaggrReal.h rename to include/clstepcore/STEPaggrReal.h index 48cd90e51..920c98907 100644 --- a/src/clstepcore/STEPaggrReal.h +++ b/include/clstepcore/STEPaggrReal.h @@ -1,7 +1,7 @@ #ifndef STEPAGGRREAL_H #define STEPAGGRREAL_H -#include "STEPaggregate.h" +#include "clstepcore/STEPaggregate.h" #include class SC_CORE_EXPORT RealAggregate : public STEPaggregate { diff --git a/src/clstepcore/STEPaggrSelect.h b/include/clstepcore/STEPaggrSelect.h similarity index 93% rename from src/clstepcore/STEPaggrSelect.h rename to include/clstepcore/STEPaggrSelect.h index 581862802..dd6621caa 100644 --- a/src/clstepcore/STEPaggrSelect.h +++ b/include/clstepcore/STEPaggrSelect.h @@ -1,7 +1,7 @@ #ifndef STEPAGGRSELECT_H #define STEPAGGRSELECT_H -#include "STEPaggregate.h" +#include "clstepcore/STEPaggregate.h" #include /** \file STEPaggrSelect.h @@ -11,7 +11,7 @@ /** * * \class SelectAggregate - ** This is a minimal represention for a collection of SDAI_Select + ** This is a minimal representation for a collection of SDAI_Select */ class SC_CORE_EXPORT SelectAggregate : public STEPaggregate { public: @@ -35,7 +35,7 @@ typedef SelectAggregate_ptr SelectAggregate_var; /** * * \class SelectNode - ** This is a minimal representions for node in lists of SDAI_Select + ** This is a minimal representation for node in lists of SDAI_Select */ class SC_CORE_EXPORT SelectNode : public STEPnode { public: @@ -68,7 +68,7 @@ class SC_CORE_EXPORT SelectNode : public STEPnode { virtual SingleLinkNode * NewNode(); - // Calling these funtions is an error. + // Calling these functions is an error. Severity StrToVal( const char * s, ErrorDescriptor * err ) { cerr << "Internal error: " << __FILE__ << __LINE__ << "\n" << _POC_ "\n"; diff --git a/src/clstepcore/STEPaggrString.h b/include/clstepcore/STEPaggrString.h similarity index 97% rename from src/clstepcore/STEPaggrString.h rename to include/clstepcore/STEPaggrString.h index 6f5cc8331..93aa1636e 100644 --- a/src/clstepcore/STEPaggrString.h +++ b/include/clstepcore/STEPaggrString.h @@ -1,7 +1,7 @@ #ifndef STEPAGGRSTRING_H #define STEPAGGRSTRING_H -#include "STEPaggregate.h" +#include "clstepcore/STEPaggregate.h" #include /** \file STEPaggrString.h diff --git a/src/clstepcore/STEPaggregate.h b/include/clstepcore/STEPaggregate.h similarity index 89% rename from src/clstepcore/STEPaggregate.h rename to include/clstepcore/STEPaggregate.h index df2178ee9..0acb638d6 100644 --- a/src/clstepcore/STEPaggregate.h +++ b/include/clstepcore/STEPaggregate.h @@ -17,11 +17,11 @@ class STEPaggregate; class TypeDescriptor; #include -#include -#include -#include -#include -#include +#include "clutils/errordesc.h" +#include "clstepcore/SingleLinkList.h" +#include "clstepcore/baseType.h" +#include "clstepcore/sdai.h" +#include "clstepcore/STEPundefined.h" #include #define AGGR_NULL &NilSTEPaggregate @@ -110,14 +110,14 @@ class SC_CORE_EXPORT STEPnode : public SingleLinkNode { }; typedef STEPnode * STEPnodeH; -#include "STEPaggrGeneric.h" -#include "STEPaggrEntity.h" -#include "STEPaggrSelect.h" -#include "STEPaggrString.h" -#include "STEPaggrBinary.h" -#include "STEPaggrEnum.h" -#include "STEPaggrReal.h" -#include "STEPaggrInt.h" +#include "clstepcore/STEPaggrGeneric.h" +#include "clstepcore/STEPaggrEntity.h" +#include "clstepcore/STEPaggrSelect.h" +#include "clstepcore/STEPaggrString.h" +#include "clstepcore/STEPaggrBinary.h" +#include "clstepcore/STEPaggrEnum.h" +#include "clstepcore/STEPaggrReal.h" +#include "clstepcore/STEPaggrInt.h" /****************************************************************** ** FIXME The following classes are currently stubs diff --git a/src/clstepcore/STEPattribute.h b/include/clstepcore/STEPattribute.h similarity index 93% rename from src/clstepcore/STEPattribute.h rename to include/clstepcore/STEPattribute.h index e3b43e0b4..f496fa46c 100644 --- a/src/clstepcore/STEPattribute.h +++ b/include/clstepcore/STEPattribute.h @@ -15,10 +15,10 @@ #include #include -#include -#include +#include "clutils/errordesc.h" +#include "clstepcore/baseType.h" -#include +#include "clstepcore/sdai.h" /** \def REAL_NUM_PRECISION * this is used to set a const int Real_Num_Precision @@ -75,21 +75,15 @@ extern SC_CORE_EXPORT void PushPastAggr1Dim( istream & in, std::string & s, Erro class SC_CORE_EXPORT STEPattribute { friend ostream & operator<< ( ostream &, STEPattribute & ); friend class SDAI_Application_instance; - protected: - bool _derive; - bool _mustDeletePtr; ///if a member uses new to create an object in ptr - ErrorDescriptor _error; - STEPattribute * _redefAttr; - const AttrDescriptor * aDesc; - int refCount; + public: /** \union ptr - ** You know which of these to use based on the return value of - ** NonRefType() - see below. BASE_TYPE is defined in baseType.h - ** This variable points to an appropriate member variable in the entity - ** class in the generated schema class library (the entity class is - ** inherited from SDAI_Application_instance) - */ + ** You know which of these to use based on the return value of + ** NonRefType() - see below. BASE_TYPE is defined in baseType.h + ** This variable points to an appropriate member variable in the entity + ** class in the generated schema class library (the entity class is + ** inherited from SDAI_Application_instance) + */ union attrUnion { SDAI_String * S; // STRING_TYPE SDAI_Integer * i; // INTEGER_TYPE (Integer is a long int) @@ -103,6 +97,18 @@ class SC_CORE_EXPORT STEPattribute { void * p; } ptr; + + protected: + bool _derive; + bool _mustDeletePtr; ///if a member uses new to create an object in ptr + ErrorDescriptor _error; + STEPattribute * _redefAttr; + public: + const AttrDescriptor * aDesc; + + protected: + int refCount; + char SkipBadAttr( istream & in, char * StopChars ); void AddErrorInfo(); void STEPwriteError( ostream& out, unsigned int line, const char* desc ); @@ -137,6 +143,7 @@ class SC_CORE_EXPORT STEPattribute { /// return the attr value as a string string asStr( const char * currSch = 0 ) const; + const char * asStr( std::string &, const char * = 0 ) const; /// put the attr value in ostream void STEPwrite( ostream & out = cout, const char * currSch = 0 ); @@ -167,11 +174,6 @@ class SC_CORE_EXPORT STEPattribute { SCLundefined * Undefined(); ///@} - /// allows direct access to the union containing attr data (dangerous!) - attrUnion * Raw() { - return & ptr; - } - /** * These functions allow setting the attribute value. * Attr type is verified using an assertion. @@ -206,7 +208,7 @@ class SC_CORE_EXPORT STEPattribute { } const char * Name() const; - const char * TypeName() const; + std::string TypeName() const; BASE_TYPE Type() const; BASE_TYPE NonRefType() const; BASE_TYPE BaseType() const; diff --git a/src/clstepcore/STEPattributeList.h b/include/clstepcore/STEPattributeList.h similarity index 97% rename from src/clstepcore/STEPattributeList.h rename to include/clstepcore/STEPattributeList.h index 9159f4664..54aca69b4 100644 --- a/src/clstepcore/STEPattributeList.h +++ b/include/clstepcore/STEPattributeList.h @@ -16,7 +16,7 @@ class STEPattribute; #include -#include +#include "clstepcore/SingleLinkList.h" class STEPattributeList; diff --git a/src/clstepcore/STEPcomplex.h b/include/clstepcore/STEPcomplex.h similarity index 91% rename from src/clstepcore/STEPcomplex.h rename to include/clstepcore/STEPcomplex.h index 9de151d43..3c8a75fc3 100644 --- a/src/clstepcore/STEPcomplex.h +++ b/include/clstepcore/STEPcomplex.h @@ -2,11 +2,11 @@ #define STEPCOMPLEX_H #include -#include -#include -#include -#include -#include +#include "clutils/errordesc.h" +#include "clstepcore/sdai.h" +#include "clstepcore/baseType.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/Registry.h" #include @@ -42,7 +42,14 @@ class SC_CORE_EXPORT STEPcomplex : public SDAI_Application_instance { STEPcomplex * head; Registry * _registry; int visited; ///< used when reading (or as you wish?) +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif STEPcomplex_attr_data_list _attr_data_list; ///< attrs are created with a pointer to data; this stores them for deletion +#ifdef _MSC_VER +#pragma warning( pop ) +#endif public: STEPcomplex( Registry * registry, int fileid ); STEPcomplex( Registry * registry, const std::string ** names, int fileid, diff --git a/src/clstepcore/STEPinvAttrList.h b/include/clstepcore/STEPinvAttrList.h similarity index 98% rename from src/clstepcore/STEPinvAttrList.h rename to include/clstepcore/STEPinvAttrList.h index 342720065..ccbb733b0 100644 --- a/src/clstepcore/STEPinvAttrList.h +++ b/include/clstepcore/STEPinvAttrList.h @@ -15,7 +15,7 @@ class Inverse_attribute; #include -#include +#include "clstepcore/SingleLinkList.h" class STEPinvAttrList; class EntityAggregate; diff --git a/src/clstepcore/STEPundefined.h b/include/clstepcore/STEPundefined.h similarity index 85% rename from src/clstepcore/STEPundefined.h rename to include/clstepcore/STEPundefined.h index 88abe110f..9cbb87ee7 100644 --- a/src/clstepcore/STEPundefined.h +++ b/include/clstepcore/STEPundefined.h @@ -13,13 +13,20 @@ */ #include -#include +#include "clutils/errordesc.h" #include -#include +#include "clstepcore/read_func.h" class SC_CORE_EXPORT SCLundefined { protected: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string val; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif public: // INPUT diff --git a/src/clstepcore/SingleLinkList.h b/include/clstepcore/SingleLinkList.h similarity index 100% rename from src/clstepcore/SingleLinkList.h rename to include/clstepcore/SingleLinkList.h diff --git a/src/clstepcore/SubSuperIterators.h b/include/clstepcore/SubSuperIterators.h similarity index 99% rename from src/clstepcore/SubSuperIterators.h rename to include/clstepcore/SubSuperIterators.h index 9ca78765b..ccc059d28 100644 --- a/src/clstepcore/SubSuperIterators.h +++ b/include/clstepcore/SubSuperIterators.h @@ -1,8 +1,8 @@ #ifndef SUB_SUPER_ITERATORS #define SUB_SUPER_ITERATORS -#include "ExpDict.h" -#include "ExpDict.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/ExpDict.h" #include #include diff --git a/src/clstepcore/aggrTypeDescriptor.h b/include/clstepcore/aggrTypeDescriptor.h similarity index 95% rename from src/clstepcore/aggrTypeDescriptor.h rename to include/clstepcore/aggrTypeDescriptor.h index 9126b8116..0031adf2d 100644 --- a/src/clstepcore/aggrTypeDescriptor.h +++ b/include/clstepcore/aggrTypeDescriptor.h @@ -2,7 +2,7 @@ #define AGGRTYPEDESCRIPTOR_H #include "typeDescriptor.h" -#include "create_Aggr.h" +#include "clstepcore/create_Aggr.h" #include "assert.h" @@ -35,7 +35,14 @@ class SC_CORE_EXPORT AggrTypeDescriptor : public TypeDescriptor { AggrBoundTypeEnum _bound1_type, _bound2_type; boundCallbackFn _bound1_callback, _bound2_callback; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string _bound1_str, _bound2_str; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif public: @@ -50,7 +57,7 @@ class SC_CORE_EXPORT AggrTypeDescriptor : public TypeDescriptor { AggrTypeDescriptor( const char * nm, PrimitiveType ft, Schema * origSchema, const char * d, AggregateCreator f = 0 ) - : TypeDescriptor( nm, ft, origSchema, d ), _bound1( 0 ), _bound2( 0 ), _uniqueElements( 0 ), _aggrDomainType( NULL ), CreateNewAggr( f ) { } + : TypeDescriptor( nm, ft, origSchema, d ), _bound1( 0 ), _bound2( 0 ), _uniqueElements( 0 ), _aggrDomainType( NULL ), CreateNewAggr( f ), _bound1_type( bound_unset ), _bound2_type( bound_unset ), _bound1_callback( NULL ), _bound2_callback( NULL ) { } virtual ~AggrTypeDescriptor(); diff --git a/src/clstepcore/attrDescriptor.h b/include/clstepcore/attrDescriptor.h similarity index 99% rename from src/clstepcore/attrDescriptor.h rename to include/clstepcore/attrDescriptor.h index cee4d13bc..c3d6493dd 100644 --- a/src/clstepcore/attrDescriptor.h +++ b/include/clstepcore/attrDescriptor.h @@ -3,7 +3,7 @@ #include "typeDescriptor.h" -#include "sdaiEnum.h" +#include "cldai/sdaiEnum.h" #include "sc_export.h" diff --git a/src/clstepcore/attrDescriptorList.h b/include/clstepcore/attrDescriptorList.h similarity index 100% rename from src/clstepcore/attrDescriptorList.h rename to include/clstepcore/attrDescriptorList.h diff --git a/src/clstepcore/baseType.h b/include/clstepcore/baseType.h similarity index 100% rename from src/clstepcore/baseType.h rename to include/clstepcore/baseType.h diff --git a/src/clstepcore/complexSupport.h b/include/clstepcore/complexSupport.h similarity index 97% rename from src/clstepcore/complexSupport.h rename to include/clstepcore/complexSupport.h index 46b673b46..34e78814e 100644 --- a/src/clstepcore/complexSupport.h +++ b/include/clstepcore/complexSupport.h @@ -18,7 +18,7 @@ #include #include using namespace std; -#include "Str.h" +#include "clutils/Str.h" #define LISTEND 999 /** \def LISTEND @@ -132,7 +132,7 @@ class SC_CORE_EXPORT EntNode { private: MarkType mark; - char name[BUFSIZ]; + char name[BUFSIZ+1]; bool multSupers; ///< do I correspond to an entity with >1 supertype? EntNode * lastSmaller( EntNode * ); ///< used by ::sort() }; @@ -173,26 +173,27 @@ class SC_CORE_EXPORT EntList { // but all we need. EntList * firstNot( JoinType ); EntList * nextNot( JoinType j ) { - return next->firstNot( j ); + return ( next ) ? next->firstNot( j ) : NULL; } EntList * firstWanted( MatchType ); EntList * nextWanted( MatchType mat ) { - return next->firstWanted( mat ); + return ( next ) ? next->firstWanted( mat ) : NULL; } EntList * lastNot( JoinType ); EntList * prevNot( JoinType j ) { - return prev->lastNot( j ); + return ( prev ) ? prev->lastNot( j ) : NULL; } EntList * lastWanted( MatchType ); EntList * prevWanted( MatchType mat ) { - return prev->lastWanted( mat ); + return ( prev ) ? prev->lastWanted( mat ) : NULL; } JoinType join; int multiple() { return ( join != SIMPLE ); } - EntList * next, *prev; + EntList * next = NULL; + EntList * prev = NULL; protected: MatchType viable; @@ -237,7 +238,7 @@ class SC_CORE_EXPORT SimpleList : public EntList { } private: - char name[BUFSIZ]; ///< Name of entity we correspond to. + char name[BUFSIZ+1]; ///< Name of entity we correspond to. MarkType I_marked; ///< Did I mark, and with what type of mark. }; diff --git a/src/clstepcore/create_Aggr.h b/include/clstepcore/create_Aggr.h similarity index 97% rename from src/clstepcore/create_Aggr.h rename to include/clstepcore/create_Aggr.h index a0483fa66..7e5fdb0b3 100644 --- a/src/clstepcore/create_Aggr.h +++ b/include/clstepcore/create_Aggr.h @@ -3,7 +3,7 @@ //typedef's for aggregate creators -#include "sdai.h" +#include "clstepcore/sdai.h" #include "sc_export.h" diff --git a/src/clstepcore/derivedAttribute.h b/include/clstepcore/derivedAttribute.h similarity index 95% rename from src/clstepcore/derivedAttribute.h rename to include/clstepcore/derivedAttribute.h index 234521a07..69e0a37cf 100644 --- a/src/clstepcore/derivedAttribute.h +++ b/include/clstepcore/derivedAttribute.h @@ -1,7 +1,7 @@ #ifndef DERIVEDATTRIBUTE_H #define DERIVEDATTRIBUTE_H -#include "attrDescriptor.h" +#include "clstepcore/attrDescriptor.h" #include "sc_export.h" diff --git a/src/clstepcore/dictSchema.h b/include/clstepcore/dictSchema.h similarity index 96% rename from src/clstepcore/dictSchema.h rename to include/clstepcore/dictSchema.h index 8cfce8a0a..96977f98e 100644 --- a/src/clstepcore/dictSchema.h +++ b/include/clstepcore/dictSchema.h @@ -27,8 +27,15 @@ class SC_CORE_EXPORT Schema : public Dictionary_instance { // non-SDAI lists Interface_spec__set_var _use_interface_list; // list of USE interfaces Interface_spec__set_var _ref_interface_list; // list of REFERENCE interfaces +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::vector< std::string > _function_list; // of EXPRESS functions std::vector< std::string > _procedure_list; // of EXPRESS procedures +#ifdef _MSC_VER +#pragma warning( pop ) +#endif Global_rule__set_var _global_rules; diff --git a/src/clstepcore/dictdefs.h b/include/clstepcore/dictdefs.h similarity index 100% rename from src/clstepcore/dictdefs.h rename to include/clstepcore/dictdefs.h diff --git a/src/clstepcore/dictionaryInstance.h b/include/clstepcore/dictionaryInstance.h similarity index 100% rename from src/clstepcore/dictionaryInstance.h rename to include/clstepcore/dictionaryInstance.h diff --git a/src/clstepcore/dispnode.h b/include/clstepcore/dispnode.h similarity index 92% rename from src/clstepcore/dispnode.h rename to include/clstepcore/dispnode.h index 1209b9c3e..fccde675c 100644 --- a/src/clstepcore/dispnode.h +++ b/include/clstepcore/dispnode.h @@ -17,14 +17,14 @@ #include -/*#include */ +/*#include "clstepcore/STEPattribute.h"*/ /*#include */ -#include +#include "clstepcore/sdai.h" -#include -#include +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" //#include -#include +#include "cleditor/editordefines.h" //#include class MgrNode; diff --git a/src/clstepcore/dispnodelist.h b/include/clstepcore/dispnodelist.h similarity index 92% rename from src/clstepcore/dispnodelist.h rename to include/clstepcore/dispnodelist.h index c4fe4dde3..6dfc697bd 100644 --- a/src/clstepcore/dispnodelist.h +++ b/include/clstepcore/dispnodelist.h @@ -17,12 +17,12 @@ #include -#include +#include "clutils/gennode.h" //#include -#include -#include -#include -#include +#include "cleditor/editordefines.h" +#include "clstepcore/mgrnode.h" +#include "clstepcore/dispnode.h" +#include "clutils/gennodelist.h" /////////////////////////////////////////////////////////////////////////////// // class DisplayNodeList diff --git a/src/clstepcore/entityDescriptor.h b/include/clstepcore/entityDescriptor.h similarity index 95% rename from src/clstepcore/entityDescriptor.h rename to include/clstepcore/entityDescriptor.h index dfc9ac230..a51810c3f 100644 --- a/src/clstepcore/entityDescriptor.h +++ b/include/clstepcore/entityDescriptor.h @@ -2,9 +2,9 @@ #define ENTITYDESCRIPTOR_H #include "typeDescriptor.h" -#include "attrDescriptor.h" +#include "clstepcore/attrDescriptor.h" #include "uniquenessRule.h" -#include "attrDescriptorList.h" +#include "clstepcore/attrDescriptorList.h" #include "inverseAttributeList.h" #include "sc_export.h" @@ -33,8 +33,15 @@ class SC_CORE_EXPORT EntityDescriptor : public TypeDescriptor { EntityDescriptorList _supertypes; // OPTIONAL AttrDescriptorList _explicitAttr; // OPTIONAL Inverse_attributeList _inverseAttr; // OPTIONAL +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string _supertype_stmt; - public: +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + public: Uniqueness_rule__set_var _uniqueness_rules; // initially a null pointer // pointer to a function that will create a new instance of a SDAI_Application_instance diff --git a/src/clstepcore/entityDescriptorList.h b/include/clstepcore/entityDescriptorList.h similarity index 100% rename from src/clstepcore/entityDescriptorList.h rename to include/clstepcore/entityDescriptorList.h diff --git a/src/clstepcore/enumTypeDescriptor.h b/include/clstepcore/enumTypeDescriptor.h similarity index 100% rename from src/clstepcore/enumTypeDescriptor.h rename to include/clstepcore/enumTypeDescriptor.h diff --git a/src/clstepcore/explicitItemId.h b/include/clstepcore/explicitItemId.h similarity index 96% rename from src/clstepcore/explicitItemId.h rename to include/clstepcore/explicitItemId.h index 31319fd08..8a4d22ca0 100644 --- a/src/clstepcore/explicitItemId.h +++ b/include/clstepcore/explicitItemId.h @@ -21,10 +21,17 @@ class SC_CORE_EXPORT Explicit_item_id : public Interfaced_item { // this ptr will be null. const TypeDescriptor * _local_definition; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif // name in originating schema - only exists if it has been renamed. Express_id _original_id; Express_id _new_id; // original or renamed name via USE or REFERENCE (non-SDAI) +#ifdef _MSC_VER +#pragma warning( pop ) +#endif const TypeDescriptor * local_definition_() const { return _local_definition; diff --git a/src/clstepcore/globalRule.h b/include/clstepcore/globalRule.h similarity index 91% rename from src/clstepcore/globalRule.h rename to include/clstepcore/globalRule.h index 1b18590c5..0987fbfbd 100644 --- a/src/clstepcore/globalRule.h +++ b/include/clstepcore/globalRule.h @@ -1,7 +1,7 @@ #ifndef GLOBALRULE_H #define GLOBALRULE_H -#include "dictionaryInstance.h" +#include "clstepcore/dictionaryInstance.h" #include "whereRule.h" #include "entityDescriptorList.h" @@ -9,7 +9,15 @@ class SC_CORE_EXPORT Global_rule : public Dictionary_instance { public: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif Express_id _name; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + Entity__set_var _entities; // not implemented Where_rule__list_var _where_rules; Schema_ptr _parent_schema; diff --git a/src/clstepcore/implicitItemId.h b/include/clstepcore/implicitItemId.h similarity index 100% rename from src/clstepcore/implicitItemId.h rename to include/clstepcore/implicitItemId.h diff --git a/src/clstepcore/instmgr.h b/include/clstepcore/instmgr.h similarity index 93% rename from src/clstepcore/instmgr.h rename to include/clstepcore/instmgr.h index 3f185b3fb..86ed28603 100644 --- a/src/clstepcore/instmgr.h +++ b/include/clstepcore/instmgr.h @@ -27,17 +27,17 @@ // IT IS VERY IMPORTANT THAT THE ORDER OF THE FOLLOWING INCLUDE FILES // BE PRESERVED -#include -#include -#include +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" +#include "clutils/gennodearray.h" -#include -#include +#include "clstepcore/mgrnode.h" +#include "clstepcore/mgrnodelist.h" -#include -#include +#include "clstepcore/dispnode.h" +#include "clstepcore/dispnodelist.h" -#include +#include "clstepcore/mgrnodearray.h" class SC_CORE_EXPORT InstMgrBase { public: diff --git a/src/clstepcore/interfaceSpec.h b/include/clstepcore/interfaceSpec.h similarity index 71% rename from src/clstepcore/interfaceSpec.h rename to include/clstepcore/interfaceSpec.h index b06a5bb78..9eeea3f85 100644 --- a/src/clstepcore/interfaceSpec.h +++ b/include/clstepcore/interfaceSpec.h @@ -1,23 +1,37 @@ #ifndef INTERFACESPEC_H #define INTERFACESPEC_H -#include "dictionaryInstance.h" -#include "explicitItemId.h" +#include "clstepcore/dictionaryInstance.h" +#include "clstepcore/explicitItemId.h" #include "implicitItemId.h" #include "sc_export.h" class SC_CORE_EXPORT Interface_spec : public Dictionary_instance { public: - Express_id _current_schema_id; // schema containing the USE/REF stmt - // set of objects from USE/REFERENCE stmt(s) - Explicit_item_id__set_var _explicit_items; - Implicit_item_id__set_var _implicit_items; //not yet initialized for schema - - // non-SDAI, not useful for SDAI use of Interface_spec (it would need to - // be a list). - // schema that defined the USE/REFd objects - Express_id _foreign_schema_id; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif + Express_id _current_schema_id; // schema containing the USE/REF stmt +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + // set of objects from USE/REFERENCE stmt(s) + Explicit_item_id__set_var _explicit_items; + Implicit_item_id__set_var _implicit_items; //not yet initialized for schema + +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif + // non-SDAI, not useful for SDAI use of Interface_spec (it would need to + // be a list). + // schema that defined the USE/REFd objects + Express_id _foreign_schema_id; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif // non-SDAI, not useful for SDAI use of Interface_spec (it would need to // be a list of ints). diff --git a/src/clstepcore/interfacedItem.h b/include/clstepcore/interfacedItem.h similarity index 71% rename from src/clstepcore/interfacedItem.h rename to include/clstepcore/interfacedItem.h index 54871d2af..238969836 100644 --- a/src/clstepcore/interfacedItem.h +++ b/include/clstepcore/interfacedItem.h @@ -1,9 +1,9 @@ #ifndef INTERFACEDITEM_H #define INTERFACEDITEM_H -#include "dictionaryInstance.h" +#include "clstepcore/dictionaryInstance.h" -#include "sdai.h" +#include "clstepcore/sdai.h" #include "sc_export.h" @@ -14,7 +14,14 @@ class SC_CORE_EXPORT Interfaced_item : public Dictionary_instance { Interfaced_item( const char * foreign_schema ); virtual ~Interfaced_item(); public: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif Express_id _foreign_schema; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif const Express_id foreign_schema_(); // private: diff --git a/src/clstepcore/inverseAttribute.h b/include/clstepcore/inverseAttribute.h similarity index 98% rename from src/clstepcore/inverseAttribute.h rename to include/clstepcore/inverseAttribute.h index 0d02b793d..4008cdaf8 100644 --- a/src/clstepcore/inverseAttribute.h +++ b/include/clstepcore/inverseAttribute.h @@ -1,7 +1,7 @@ #ifndef INVERSEATTRIBUTE_H #define INVERSEATTRIBUTE_H -#include "attrDescriptor.h" +#include "clstepcore/attrDescriptor.h" class SC_CORE_EXPORT Inverse_attribute : public AttrDescriptor { diff --git a/src/clstepcore/inverseAttributeList.h b/include/clstepcore/inverseAttributeList.h similarity index 100% rename from src/clstepcore/inverseAttributeList.h rename to include/clstepcore/inverseAttributeList.h diff --git a/src/clstepcore/mgrnode.h b/include/clstepcore/mgrnode.h similarity index 96% rename from src/clstepcore/mgrnode.h rename to include/clstepcore/mgrnode.h index 435b6aa70..9bc96ef1d 100644 --- a/src/clstepcore/mgrnode.h +++ b/include/clstepcore/mgrnode.h @@ -18,14 +18,12 @@ class GenericNode; class DisplayNode; -#include +#include "clstepcore/sdai.h" -#include -#include +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" -#include - -#include +#include "cleditor/editordefines.h" class InstMgr; @@ -33,7 +31,7 @@ class SC_CORE_EXPORT MgrNodeBase : public GenericNode { public: virtual inline SDAI_Application_instance * GetSTEPentity() { abort(); - return nullptr; + return NULL; }; virtual ~MgrNodeBase() {}; }; diff --git a/src/clstepcore/mgrnodearray.h b/include/clstepcore/mgrnodearray.h similarity index 95% rename from src/clstepcore/mgrnodearray.h rename to include/clstepcore/mgrnodearray.h index 22019d071..c09f6995f 100644 --- a/src/clstepcore/mgrnodearray.h +++ b/include/clstepcore/mgrnodearray.h @@ -19,14 +19,14 @@ #include -#include -#include +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" //#include -#include -#include +#include "clstepcore/mgrnode.h" +#include "clstepcore/mgrnodelist.h" -#include +#include "clutils/gennodearray.h" #define ARRAY_DEFAULT_SIZE (1024) diff --git a/src/clstepcore/mgrnodelist.h b/include/clstepcore/mgrnodelist.h similarity index 94% rename from src/clstepcore/mgrnodelist.h rename to include/clstepcore/mgrnodelist.h index be822c798..e085b66c5 100644 --- a/src/clstepcore/mgrnodelist.h +++ b/include/clstepcore/mgrnodelist.h @@ -17,10 +17,10 @@ #include -#include +#include "clutils/gennode.h" //#include -#include -#include +#include "clutils/gennodelist.h" +#include "cleditor/editordefines.h" ////////////////////////////////////////////////////////////////////////////// // class MgrNodeList diff --git a/src/clstepcore/needFunc.h b/include/clstepcore/needFunc.h similarity index 100% rename from src/clstepcore/needFunc.h rename to include/clstepcore/needFunc.h diff --git a/src/clstepcore/read_func.h b/include/clstepcore/read_func.h similarity index 99% rename from src/clstepcore/read_func.h rename to include/clstepcore/read_func.h index 92cff5705..448297164 100644 --- a/src/clstepcore/read_func.h +++ b/include/clstepcore/read_func.h @@ -2,7 +2,7 @@ #define READ_FUNC_H #include -#include +#include "clstepcore/sdai.h" /// This was 512. According to 10303-21:2002 section 5.6: comment length is unlimited. FIXME need to check the code for potential problems before eliminating this limit completely. #define MAX_COMMENT_LENGTH 8192 diff --git a/src/clstepcore/realTypeDescriptor.h b/include/clstepcore/realTypeDescriptor.h similarity index 100% rename from src/clstepcore/realTypeDescriptor.h rename to include/clstepcore/realTypeDescriptor.h diff --git a/src/clstepcore/schRename.h b/include/clstepcore/schRename.h similarity index 86% rename from src/clstepcore/schRename.h rename to include/clstepcore/schRename.h index a0403a5d8..b3f7fdefd 100644 --- a/src/clstepcore/schRename.h +++ b/include/clstepcore/schRename.h @@ -4,7 +4,7 @@ #include #include -#include "Str.h" +#include "clutils/Str.h" #include "sc_export.h" @@ -22,8 +22,10 @@ class SC_CORE_EXPORT SchRename { public: SchRename( const char * sch = "\0", const char * newnm = "\0" ) : next( 0 ) { - strcpy( schName, sch ); - strcpy( newName, newnm ); + strncpy( schName, sch, BUFSIZ ); + schName[BUFSIZ] = '\0'; + strncpy( newName, newnm, BUFSIZ ); + newName[BUFSIZ] = '\0'; } ~SchRename() { delete next; @@ -41,8 +43,8 @@ class SC_CORE_EXPORT SchRename { SchRename * next; private: - char schName[BUFSIZ]; - char newName[BUFSIZ]; + char schName[BUFSIZ+1]; + char newName[BUFSIZ+1]; }; diff --git a/src/clstepcore/sdai.h b/include/clstepcore/sdai.h similarity index 91% rename from src/clstepcore/sdai.h rename to include/clstepcore/sdai.h index 7c7985a3e..f063653ce 100644 --- a/src/clstepcore/sdai.h +++ b/include/clstepcore/sdai.h @@ -18,7 +18,7 @@ * values for the EXPRESS base types. */ -#include "sc_cf.h" +#include "config.h" #include extern const char * SCLversion; @@ -27,11 +27,11 @@ extern const char * SCLversion; #include -#include "dictdefs.h" +#include "clstepcore/dictdefs.h" -#include "baseType.h" -#include "Str.h" -#include "errordesc.h" +#include "clstepcore/baseType.h" +#include "clutils/Str.h" +#include "clutils/errordesc.h" typedef std::string Express_id; @@ -40,8 +40,8 @@ class EntityDescriptor; class SelectTypeDescriptor; class InstMgrBase; -#include "STEPattributeList.h" -#include "STEPinvAttrList.h" +#include "clstepcore/STEPattributeList.h" +#include "clstepcore/STEPinvAttrList.h" class STEPattributeList; class STEPattribute; @@ -155,12 +155,12 @@ typedef char * SDAI_Time_stamp; typedef char * SDAI_Entity_name; typedef char * SDAI_Schema_name; -#include +#include "cldai/sdaiString.h" -#include +#include "cldai/sdaiBinary.h" // define Object which I am calling sdaiObject for now - DAS -#include +#include "cldai/sdaiObject.h" /****************************************************************************** ENUMERATION @@ -172,7 +172,7 @@ ENUMERATION * the value ENUM_NULL is used to represent NULL for all enumerated types *****************************************************************************/ -#include +#include "cldai/sdaiEnum.h" /****************************************************************************** BOOLEAN and LOGICAL @@ -185,11 +185,11 @@ BOOLEAN and LOGICAL // ***note*** this file needs classes from sdaiEnum.h // define DAObjectID and classes PID, PID_DA, PID_SDAI, DAObject, DAObject_SDAI -#include +#include "cldai/sdaiDaObject.h" -#include -#include +#include "clstepcore/sdaiApplication_instance.h" +#include "cldai/sdaiApplication_instance_set.h" /****************************************************************************** SELECT @@ -198,18 +198,18 @@ SELECT sdaiSelect.h ******************************************************************************/ -#include +#include "clstepcore/sdaiSelect.h" class SDAI_Model_contents; typedef SDAI_Model_contents * SDAI_Model_contents_ptr; typedef SDAI_Model_contents_ptr SDAI_Model_contents_var; -#include +#include "cldai/sdaiModel_contents_list.h" -#include -#include -#include -#include +#include "cldai/sdaiSession_instance.h" +#include "cldai/sdaiEntity_extent.h" +#include "cldai/sdaiEntity_extent_set.h" +#include "cldai/sdaiModel_contents.h" // ENTITY extern SC_CORE_EXPORT SDAI_Application_instance NilSTEPentity; @@ -246,7 +246,7 @@ ReadEntityRef( istream & in, ErrorDescriptor * err, const char * tokenList, /****************************************************************************** AGGREGATE TYPES - Aggregate types are accessed generically. (There are not seperate + Aggregate types are accessed generically. (There are not separate classes for the different types of aggregates.) Aggregates are implemented through the STEPaggregate class. diff --git a/src/clstepcore/sdaiApplication_instance.h b/include/clstepcore/sdaiApplication_instance.h similarity index 95% rename from src/clstepcore/sdaiApplication_instance.h rename to include/clstepcore/sdaiApplication_instance.h index bcf5ef43d..4e764f593 100644 --- a/src/clstepcore/sdaiApplication_instance.h +++ b/include/clstepcore/sdaiApplication_instance.h @@ -16,7 +16,7 @@ #include #include -#include +#include "cldai/sdaiDaObject.h" class EntityAggregate; class Inverse_attribute; @@ -36,9 +36,16 @@ class SC_CORE_EXPORT SDAI_Application_instance : public SDAI_DAObject_SDAI { public: typedef std::map< const Inverse_attribute * const, iAstruct> iAMap_t; - protected: const EntityDescriptor * eDesc; + protected: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif iAMap_t iAMap; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif bool _complex; public: //TODO make these private? @@ -51,7 +58,14 @@ class SC_CORE_EXPORT SDAI_Application_instance : public SDAI_DAObject_SDAI { int STEPfile_id; ErrorDescriptor _error; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string p21Comment; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif /** ** head entity for multiple inheritance. If it is null then this @@ -75,10 +89,6 @@ class SC_CORE_EXPORT SDAI_Application_instance : public SDAI_DAObject_SDAI { /// initialize inverse attribute list void InitIAttrs(); - void setEDesc( const EntityDescriptor * const ed ) { - eDesc = ed; - } - const EntityDescriptor * getEDesc() const; void StepFileId( int fid ) { STEPfile_id = fid; } diff --git a/src/clstepcore/sdaiSelect.h b/include/clstepcore/sdaiSelect.h similarity index 100% rename from src/clstepcore/sdaiSelect.h rename to include/clstepcore/sdaiSelect.h diff --git a/src/clstepcore/selectTypeDescriptor.h b/include/clstepcore/selectTypeDescriptor.h similarity index 100% rename from src/clstepcore/selectTypeDescriptor.h rename to include/clstepcore/selectTypeDescriptor.h diff --git a/src/clstepcore/stringTypeDescriptor.h b/include/clstepcore/stringTypeDescriptor.h similarity index 100% rename from src/clstepcore/stringTypeDescriptor.h rename to include/clstepcore/stringTypeDescriptor.h diff --git a/src/clstepcore/typeDescriptor.h b/include/clstepcore/typeDescriptor.h similarity index 98% rename from src/clstepcore/typeDescriptor.h rename to include/clstepcore/typeDescriptor.h index 24ef471c5..51a815593 100644 --- a/src/clstepcore/typeDescriptor.h +++ b/include/clstepcore/typeDescriptor.h @@ -3,7 +3,7 @@ #include "schRename.h" #include "whereRule.h" -#include "dictSchema.h" +#include "clstepcore/dictSchema.h" #include "sc_export.h" @@ -53,7 +53,7 @@ * part_label and label would be the value of the respective * _name member variables for the 2 TypeDescriptors. * \var _referentType - * will point at another TypeDescriptor furthur specifying + * will point at another TypeDescriptor further specifying * the type in all cases except when the type is directly * an enum or select. i.e. in the following... _referentType for * the 1st type does not point at anything and for the 2nd it does: @@ -74,7 +74,7 @@ ** var _referentType * For the TypeDescriptors describing the EXPRESS base types this will * be a null pointer. For all other TypeDescriptors this will point - * to another TypeDescriptor which furthur describes the type. e.g. + * to another TypeDescriptor which further describes the type. e.g. * TYPE part_label = label END_TYPE; TYPE label = STRING END_TYPE; * part_label's _referentType will point to the TypeDescriptor for * label. label's _referentType will point to the TypeDescriptor @@ -111,7 +111,7 @@ class SC_CORE_EXPORT TypeDescriptor { /// schema which USEs/ REFERENCEs this. (A complete list of /// alternate names is stored in altNames below. _altname pro- /// vides storage space for the currently used one.) - char _altname[BUFSIZ]; + char _altname[BUFSIZ+1]; /// contains list of renamings of type - used by other schemas /// which USE/ REFERENCE this diff --git a/src/clstepcore/typeDescriptorList.h b/include/clstepcore/typeDescriptorList.h similarity index 100% rename from src/clstepcore/typeDescriptorList.h rename to include/clstepcore/typeDescriptorList.h diff --git a/src/clstepcore/typeOrRuleVar.h b/include/clstepcore/typeOrRuleVar.h similarity index 89% rename from src/clstepcore/typeOrRuleVar.h rename to include/clstepcore/typeOrRuleVar.h index 09f78da59..c698c5bd5 100644 --- a/src/clstepcore/typeOrRuleVar.h +++ b/include/clstepcore/typeOrRuleVar.h @@ -1,7 +1,7 @@ #ifndef TYPEORRULEVAR_H #define TYPEORRULEVAR_H -#include "dictionaryInstance.h" +#include "clstepcore/dictionaryInstance.h" #include "sc_export.h" diff --git a/src/clstepcore/uniquenessRule.h b/include/clstepcore/uniquenessRule.h similarity index 90% rename from src/clstepcore/uniquenessRule.h rename to include/clstepcore/uniquenessRule.h index 8ed5fc624..b42a7414d 100644 --- a/src/clstepcore/uniquenessRule.h +++ b/include/clstepcore/uniquenessRule.h @@ -1,9 +1,9 @@ #ifndef UNIQUENESSRULE_H #define UNIQUENESSRULE_H -#include "dictionaryInstance.h" +#include "clstepcore/dictionaryInstance.h" -#include "sdai.h" +#include "clstepcore/sdai.h" #include "sc_export.h" @@ -11,13 +11,21 @@ class EntityDescriptor; class SC_CORE_EXPORT Uniqueness_rule : public Dictionary_instance { public: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif Express_id _label; - const EntityDescriptor * _parent_entity; // non-SDAI std::string _comment; /** Comment contained in the EXPRESS. * Should be properly formatted to include (* *) * Will be written to EXPRESS as-is (w/out formatting) */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + const EntityDescriptor * _parent_entity; Uniqueness_rule(); Uniqueness_rule( const Uniqueness_rule & ); diff --git a/src/clstepcore/whereRule.h b/include/clstepcore/whereRule.h similarity index 89% rename from src/clstepcore/whereRule.h rename to include/clstepcore/whereRule.h index 2f4487bfd..98952d049 100644 --- a/src/clstepcore/whereRule.h +++ b/include/clstepcore/whereRule.h @@ -2,21 +2,28 @@ #define WHERERULE_H #include -#include "sdai.h" -#include "dictionaryInstance.h" +#include "clstepcore/sdai.h" +#include "clstepcore/dictionaryInstance.h" #include "typeOrRuleVar.h" #include "sc_export.h" class SC_CORE_EXPORT Where_rule : public Dictionary_instance { public: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif Express_id _label; - Type_or_rule_var _type_or_rule; // non-SDAI std::string _comment; // Comment contained in the EXPRESS. // Should be properly formatted to include (* *) // Will be written to EXPRESS as-is (w/out formatting) +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + Type_or_rule_var _type_or_rule; Where_rule(); Where_rule( const Where_rule & ); diff --git a/include/clutils/CMakeLists.txt b/include/clutils/CMakeLists.txt new file mode 100644 index 000000000..9992890bc --- /dev/null +++ b/include/clutils/CMakeLists.txt @@ -0,0 +1,20 @@ +set(UTILS_HDRS + dirobj.h + errordesc.h + gennodearray.h + gennode.h + gennodelist.h + sc_hash.h + Str.h + ) + +install(FILES ${UTILS_HDRS} + DESTINATION ${INCLUDE_DIR}/stepcode/clutils) + +# Local Variables: +# tab-width: 8 +# mode: cmake +# indent-tabs-mode: t +# End: +# ex: shiftwidth=2 tabstop=8 + diff --git a/src/clutils/Str.h b/include/clutils/Str.h similarity index 98% rename from src/clutils/Str.h rename to include/clutils/Str.h index f605bfdda..487a2c9e2 100644 --- a/src/clutils/Str.h +++ b/include/clutils/Str.h @@ -19,7 +19,7 @@ #include #include #include -#include +#include "clutils/errordesc.h" #ifndef STRING_DELIM #define STRING_DELIM '\'' diff --git a/src/clutils/dirobj.h b/include/clutils/dirobj.h similarity index 95% rename from src/clutils/dirobj.h rename to include/clutils/dirobj.h index a89e28dad..fe847a1e5 100644 --- a/src/clutils/dirobj.h +++ b/include/clutils/dirobj.h @@ -33,7 +33,7 @@ // /////////////////////////////////////////////////////////////////////////////// -#include +#include "config.h" #include #include @@ -61,10 +61,10 @@ class SC_UTILS_EXPORT DirObj { const char * File( int index ); // check for file in the currently loaded directory bool FileExists( const char * file ) { - return Index( file ) ? 1 : 0; + return Index( file ) != -1; } bool FileExists( const std::string & file ) { - return Index( file.c_str() ) ? true : false; + return Index( file.c_str() ) != -1; } int Count(); diff --git a/src/clutils/errordesc.h b/include/clutils/errordesc.h similarity index 96% rename from src/clutils/errordesc.h rename to include/clutils/errordesc.h index 7b5c9db31..4ab284b2d 100644 --- a/src/clutils/errordesc.h +++ b/include/clutils/errordesc.h @@ -55,7 +55,14 @@ typedef int DebugLevel; class SC_UTILS_EXPORT ErrorDescriptor { private: +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::string _userMsg, _detailMsg; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif protected: Severity _severity; diff --git a/src/clutils/gennode.h b/include/clutils/gennode.h similarity index 100% rename from src/clutils/gennode.h rename to include/clutils/gennode.h diff --git a/src/clutils/gennodearray.h b/include/clutils/gennodearray.h similarity index 98% rename from src/clutils/gennodearray.h rename to include/clutils/gennodearray.h index 4c0ee075a..1643f05e6 100644 --- a/src/clutils/gennodearray.h +++ b/include/clutils/gennodearray.h @@ -26,7 +26,7 @@ #include #include // to get bcopy for CenterLine -#include +#include "clutils/gennode.h" // the initial size of the array #define ARRAY_DEFAULT_SIZE (1024) diff --git a/src/clutils/gennodelist.h b/include/clutils/gennodelist.h similarity index 100% rename from src/clutils/gennodelist.h rename to include/clutils/gennodelist.h diff --git a/src/clutils/sc_hash.h b/include/clutils/sc_hash.h similarity index 100% rename from src/clutils/sc_hash.h rename to include/clutils/sc_hash.h diff --git a/include/config.h.in b/include/config.h.in new file mode 100644 index 000000000..63ccc4ed1 --- /dev/null +++ b/include/config.h.in @@ -0,0 +1,31 @@ +#ifndef SCL_CF_H +#define SCL_CF_H + +/**** Define statements for CMake ****/ +#cmakedefine SC_VERSION "@SC_VERSION@" +#cmakedefine HAVE_NDIR_H 1 +#cmakedefine HAVE_STDINT_H 1 +#cmakedefine HAVE_SYS_STAT_H 1 +#cmakedefine HAVE_SYS_PARAM_H 1 +#cmakedefine HAVE_SYSENT_H 1 +#cmakedefine HAVE_UNISTD_H 1 +#cmakedefine HAVE_DIRENT_H 1 +#cmakedefine HAVE_STDBOOL_H 1 +#cmakedefine HAVE_PROCESS_H 1 +#cmakedefine HAVE_IO_H 1 + +#cmakedefine SC_TRACE_FPRINTF 1 + +#cmakedefine HAVE_ABS 1 +#cmakedefine HAVE_MEMCPY 1 +#cmakedefine HAVE_MEMMOVE 1 +#cmakedefine HAVE_GETOPT 1 +#cmakedefine HAVE_VSNPRINTF 1 + +#cmakedefine HAVE_SSIZE_T 1 + +#cmakedefine HAVE_STD_THREAD 1 +#cmakedefine HAVE_STD_CHRONO 1 +#cmakedefine HAVE_NULLPTR 1 + +#endif /* SCL_CF_H */ diff --git a/include/exppp/exppp.h b/include/exppp/exppp.h index f6159cbf5..e519aa70b 100644 --- a/include/exppp/exppp.h +++ b/include/exppp/exppp.h @@ -1,7 +1,7 @@ #ifndef EXPPP_H #define EXPPP_H -#include +#include #include diff --git a/include/express/alg.h b/include/express/alg.h index 8f457638a..bc76c5ddd 100644 --- a/include/express/alg.h +++ b/include/express/alg.h @@ -119,16 +119,16 @@ extern SC_EXPRESS_EXPORT struct freelist_head WHERE_fl; /* macro function definitions */ /******************************/ -#define ALG_new() (struct Algorithm *)MEM_new(&ALG_fl); -#define ALG_destroy(x) MEM_destroy(&ALG_fl,(Freelist *)(Generic)x) -#define FUNC_new() (struct Function_ *)MEM_new(&FUNC_fl) -#define FUNC_destroy(x) MEM_destroy(&FUNC_fl,(Freelist *)(Generic)x) -#define RULE_new() (struct Rule_ *)MEM_new(&RULE_fl) -#define RULE_destroy(x) MEM_destroy(&RULE_fl,(Freelist *)(Generic)x) -#define PROC_new() (struct Procedure_ *)MEM_new(&PROC_fl) -#define PROC_destroy(x) MEM_destroy(&PROC_fl,(Freelist *)(Generic)x) -#define WHERE_new() (struct Where_ *)MEM_new(&WHERE_fl) -#define WHERE_destroy(x) MEM_destroy(&WHERE_fl,(Freelist *)(Generic)x) +#define ALG_new() (struct Algorithm *)ALLOC_new(&ALG_fl); +#define ALG_destroy(x) ALLOC_destroy(&ALG_fl,(Freelist *)x) +#define FUNC_new() (struct Function_ *)ALLOC_new(&FUNC_fl) +#define FUNC_destroy(x) ALLOC_destroy(&FUNC_fl,(Freelist *)x) +#define RULE_new() (struct Rule_ *)ALLOC_new(&RULE_fl) +#define RULE_destroy(x) ALLOC_destroy(&RULE_fl,(Freelist *)x) +#define PROC_new() (struct Procedure_ *)ALLOC_new(&PROC_fl) +#define PROC_destroy(x) ALLOC_destroy(&PROC_fl,(Freelist *)x) +#define WHERE_new() (struct Where_ *)ALLOC_new(&WHERE_fl) +#define WHERE_destroy(x) ALLOC_destroy(&WHERE_fl,(Freelist *)x) #define ALGput_name(algorithm, name) SCOPEput_name(algorithm,name) #define ALGget_name(algorithm) SCOPEget_name(algorithm) @@ -161,8 +161,8 @@ extern SC_EXPRESS_EXPORT struct freelist_head WHERE_fl; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT Scope ALGcreate PROTO( ( char ) ); -extern SC_EXPRESS_EXPORT void ALGinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void ALGput_full_text PROTO( ( Scope, int, int ) ); +extern SC_EXPRESS_EXPORT Scope ALGcreate( char ); +extern SC_EXPRESS_EXPORT void ALGinitialize( void ); +extern SC_EXPRESS_EXPORT void ALGput_full_text( Scope, int, int ); #endif /* ALGORITHM_H */ diff --git a/include/express/alloc.h b/include/express/alloc.h new file mode 100644 index 000000000..79199773a --- /dev/null +++ b/include/express/alloc.h @@ -0,0 +1,85 @@ +#ifndef ALLOC_H +#define ALLOC_H + +/* + * This work was supported by the United States Government, and is + * not subject to copyright. + * + * $Log: memory.h,v $ + * Revision 1.5 1997/01/21 19:17:11 dar + * made C++ compatible + * + * Revision 1.4 1993/10/15 18:49:23 libes + * CADDETC certified + * + * Revision 1.3 1993/02/22 21:41:13 libes + * ANSI compat + * + * Revision 1.2 1992/08/18 17:15:40 libes + * rm'd extraneous error messages + * + * Revision 1.1 1992/05/28 03:56:02 libes + * Initial revision + */ + +#include "basic.h" + +/*****************/ +/* packages used */ +/*****************/ + +#include + +/** \file alloc.h - defs for fixed size block memory allocator */ + +typedef long Align; + +union freelist { + union freelist * next; /**< next block on freelist */ + char memory; /**< user data */ + Align aligner; /**< force alignment of blocks */ +}; + +typedef union freelist Freelist; + +struct freelist_head { + int size_elt; /**< size of a single elt */ +#ifndef NOSTAT + int alloc; /**< # of allocations */ + int dealloc; + int create; /**< number of calls to create a new freelist */ + void *max; /**< end of freelist */ +#endif + int size; /**< size of a single elt incl. next ptr */ + int bytes; /**< if we run out, allocate memory by this many bytes */ + Freelist * freelist; +#ifdef SPACE_PROFILE + int count; +#endif +}; + +char * nnew(); + +#include "error.h" + +/***********************************************/ +/* space allocation macros with error package: */ +/***********************************************/ + +extern SC_EXPRESS_EXPORT int yylineno; + +/** CALLOC grabs and initializes to all 0s space for the indicated + * number of instances of the indicated type */ +#define CALLOC(ptr, num, type) \ + if (((ptr) = (type*)calloc((num), (unsigned)sizeof(type)))==NULL) { \ + fprintf(stderr,"fedex: out of space");\ + } else {} + +SC_EXPRESS_EXPORT void _ALLOCinitialize( void ); +SC_EXPRESS_EXPORT void ALLOCinitialize( struct freelist_head * flh, unsigned int size, int alloc1, int alloc2 ); +SC_EXPRESS_EXPORT void ALLOC_destroy( struct freelist_head *, Freelist * ); +SC_EXPRESS_EXPORT void * ALLOC_new( struct freelist_head * ); + +#endif /* ALLOC_H */ + + diff --git a/include/express/basic.h b/include/express/basic.h index 349e653b8..f7c6b90f0 100644 --- a/include/express/basic.h +++ b/include/express/basic.h @@ -71,7 +71,7 @@ * */ -#include +#include "config.h" #include #include @@ -82,22 +82,12 @@ #ifdef HAVE_STDBOOL_H # include #else -# include +# include #endif -/************************/ -/* Generic pointer type */ -/************************/ - -#ifdef __STDC__ -typedef void * Generic; -#else -typedef char * Generic; -#endif /* */ - -/* other handy macros */ -#define streq(x,y) (!strcmp((x),(y))) - +#if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(__cplusplus) +#define inline __inline +#endif /**************************/ /* function pointer types */ @@ -106,45 +96,8 @@ typedef char * Generic; typedef void ( *voidFuncptr )(); typedef int ( *intFuncptr )(); -/******************************/ -/* deal with inline functions */ -/******************************/ - -#if !defined(static_inline) -#if (!defined(__GNUC__) && !defined(__MSVC__)) || defined(__STRICT_ANSI) -#define static_inline -#undef supports_inline_functions -#else -#define static_inline static __inline -#define supports_inline_functions 1L -#endif /* */ -#endif /* !defined(static_inline) */ - -/* allow same declarations to suffice for both Standard and Classic C */ -/* ... at least in header files ... */ - -#ifndef CONST -# ifdef __STDC__ -# define CONST const -# else -# define CONST -# endif -#endif - -#ifndef PROTO -# ifdef __STDC__ -# define PROTO(x) x -# else - -# if defined(__CLCC__) || defined(__MSVC__) || defined(__BORLAND__) -# define PROTO(x) x -#else -# define PROTO(x) () -# endif - -# endif -#endif - -#endif /* */ +/* Option index - can we get rid of this? */ +extern SC_EXPRESS_EXPORT int sc_optind; +#endif /* BASIC_H */ diff --git a/include/express/caseitem.h b/include/express/caseitem.h index d3b8fb464..1c75f55bd 100644 --- a/include/express/caseitem.h +++ b/include/express/caseitem.h @@ -83,10 +83,10 @@ extern SC_EXPRESS_EXPORT struct freelist_head CASE_IT_fl; /* function prototypes */ /***********************/ -#define CASE_IT_new() (struct Case_Item_ *)MEM_new(&CASE_IT_fl) -#define CASE_IT_destroy(x) MEM_destroy(&CASE_IT_fl,(Freelist *)(Generic)x) +#define CASE_IT_new() (struct Case_Item_ *)ALLOC_new(&CASE_IT_fl) +#define CASE_IT_destroy(x) ALLOC_destroy(&CASE_IT_fl,(Freelist *)x) -extern SC_EXPRESS_EXPORT Case_Item CASE_ITcreate PROTO( ( Linked_List, struct Statement_ * ) ); -extern SC_EXPRESS_EXPORT void CASE_ITinitialize PROTO( ( void ) ); +extern SC_EXPRESS_EXPORT Case_Item CASE_ITcreate( Linked_List, struct Statement_ * ); +extern SC_EXPRESS_EXPORT void CASE_ITinitialize( void ); #endif /*CASE_ITEM_H*/ diff --git a/include/express/dict.h b/include/express/dict.h index b46709456..f289ecca3 100644 --- a/include/express/dict.h +++ b/include/express/dict.h @@ -97,14 +97,14 @@ extern SC_EXPRESS_EXPORT char DICT_type; /**< set as a side-effect of DICT look /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT void DICTinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void DICTcleanup PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT int DICTdefine PROTO( ( Dictionary, char *, Generic, Symbol *, char ) ); -extern SC_EXPRESS_EXPORT int DICT_define PROTO( ( Dictionary, char *, Generic, Symbol *, char ) ); -extern SC_EXPRESS_EXPORT void DICTundefine PROTO( ( Dictionary, char * ) ); -extern SC_EXPRESS_EXPORT Generic DICTlookup PROTO( ( Dictionary, char * ) ); -extern SC_EXPRESS_EXPORT Generic DICTlookup_symbol PROTO( ( Dictionary, char *, Symbol ** ) ); -extern SC_EXPRESS_EXPORT Generic DICTdo PROTO( ( DictionaryEntry * ) ); -extern SC_EXPRESS_EXPORT void DICTprint PROTO( ( Dictionary ) ); +extern SC_EXPRESS_EXPORT void DICTinitialize( void ); +extern SC_EXPRESS_EXPORT void DICTcleanup( void ); +extern SC_EXPRESS_EXPORT int DICTdefine( Dictionary, char *, void *, Symbol *, char ); +extern SC_EXPRESS_EXPORT int DICT_define( Dictionary, char *, void *, Symbol *, char ); +extern SC_EXPRESS_EXPORT void DICTundefine( Dictionary, char * ); +extern SC_EXPRESS_EXPORT void * DICTlookup( Dictionary, char * ); +extern SC_EXPRESS_EXPORT void * DICTlookup_symbol( Dictionary, char *, Symbol ** ); +extern SC_EXPRESS_EXPORT void * DICTdo( DictionaryEntry * ); +extern SC_EXPRESS_EXPORT void DICTprint( Dictionary ); #endif /*DICTIONARY_H*/ diff --git a/include/express/entity.h b/include/express/entity.h index 8a0ab891b..3440dc9bc 100644 --- a/include/express/entity.h +++ b/include/express/entity.h @@ -109,8 +109,8 @@ extern SC_EXPRESS_EXPORT int ENTITY_MARK; /* macro function definitions */ /******************************/ -#define ENTITY_new() (struct Entity_ *)MEM_new(&ENTITY_fl) -#define ENTITY_destroy(x) MEM_destroy(&ENTITY_fl,(Freelist *)(char *)x) +#define ENTITY_new() (struct Entity_ *)ALLOC_new(&ENTITY_fl) +#define ENTITY_destroy(x) ALLOC_destroy(&ENTITY_fl,(Freelist *)(char *)x) #define ENTITYget_symbol(e) SCOPEget_symbol(e) /* returns a function (i.e., which can be passed to other functions) */ @@ -140,19 +140,19 @@ extern SC_EXPRESS_EXPORT int ENTITY_MARK; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT struct Scope_ * ENTITYcreate PROTO( ( struct Symbol_ * ) ); -extern SC_EXPRESS_EXPORT void ENTITYinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void ENTITYadd_attribute PROTO( ( struct Scope_ *, struct Variable_ * ) ); -extern SC_EXPRESS_EXPORT struct Scope_ * ENTITYcopy PROTO( ( struct Scope_ * ) ); -extern SC_EXPRESS_EXPORT Entity ENTITYfind_inherited_entity PROTO( ( struct Scope_ *, char *, int ) ); -extern SC_EXPRESS_EXPORT Variable ENTITYfind_inherited_attribute PROTO( ( struct Scope_ *, char *, struct Symbol_ ** ) ); -extern SC_EXPRESS_EXPORT Variable ENTITYresolve_attr_ref PROTO( ( Entity, Symbol *, Symbol * ) ); -extern SC_EXPRESS_EXPORT bool ENTITYhas_immediate_supertype PROTO( ( Entity, Entity ) ); -extern SC_EXPRESS_EXPORT Variable ENTITYget_named_attribute PROTO( ( Entity, char * ) ); -extern SC_EXPRESS_EXPORT Linked_List ENTITYget_all_attributes PROTO( ( Entity ) ); -extern SC_EXPRESS_EXPORT bool ENTITYhas_supertype PROTO( ( Entity, Entity ) ); -extern SC_EXPRESS_EXPORT void ENTITYadd_instance PROTO( ( Entity, Generic ) ); -extern SC_EXPRESS_EXPORT int ENTITYget_initial_offset PROTO( ( Entity ) ); -extern SC_EXPRESS_EXPORT int ENTITYdeclares_variable PROTO( ( Entity, struct Variable_ * ) ); +extern SC_EXPRESS_EXPORT struct Scope_ * ENTITYcreate( struct Symbol_ * ); +extern SC_EXPRESS_EXPORT void ENTITYinitialize( void ); +extern SC_EXPRESS_EXPORT void ENTITYadd_attribute( struct Scope_ *, struct Variable_ * ); +extern SC_EXPRESS_EXPORT struct Scope_ * ENTITYcopy( struct Scope_ * ); +extern SC_EXPRESS_EXPORT Entity ENTITYfind_inherited_entity( struct Scope_ *, char *, int ); +extern SC_EXPRESS_EXPORT Variable ENTITYfind_inherited_attribute( struct Scope_ *, char *, struct Symbol_ ** ); +extern SC_EXPRESS_EXPORT Variable ENTITYresolve_attr_ref( Entity, Symbol *, Symbol * ); +extern SC_EXPRESS_EXPORT bool ENTITYhas_immediate_supertype( Entity, Entity ); +extern SC_EXPRESS_EXPORT Variable ENTITYget_named_attribute( Entity, char * ); +extern SC_EXPRESS_EXPORT Linked_List ENTITYget_all_attributes( Entity ); +extern SC_EXPRESS_EXPORT bool ENTITYhas_supertype( Entity, Entity ); +extern SC_EXPRESS_EXPORT void ENTITYadd_instance( Entity, void *); +extern SC_EXPRESS_EXPORT int ENTITYget_initial_offset( Entity ); +extern SC_EXPRESS_EXPORT int ENTITYdeclares_variable( Entity, struct Variable_ * ); #endif /* ENTITY_H */ diff --git a/include/express/error.h b/include/express/error.h index 5e62656d6..4d9c1dde8 100644 --- a/include/express/error.h +++ b/include/express/error.h @@ -28,51 +28,134 @@ * prettied up interface to print_objects_when_running */ -#include -#include "basic.h" /* get basic definitions */ #include -/*************/ -/* constants */ -/*************/ - -#define ERROR_none (Error)NULL -#define ERROR_MAX 100 +#include "sc_export.h" +#include "basic.h" /* get basic definitions */ /*****************/ /* packages used */ /*****************/ -#include "memory.h" +#include "alloc.h" #include "symbol.h" +enum ErrorCode { + /* dict.c */ + DUPLICATE_DECL = 1, + DUPLICATE_DECL_DIFF_FILE, + /* error.c */ + SUBORDINATE_FAILED, + SYNTAX_EXPECTING, + /* expr.c */ + INTEGER_EXPRESSION_EXPECTED, + INTERNAL_UNRECOGNISED_OP_IN_EXPRESOLVE, + ATTRIBUTE_REF_ON_AGGREGATE, + ATTRIBUTE_REF_FROM_NON_ENTITY, + INDEXING_ILLEGAL, + WARN_INDEXING_MIXED, + ENUM_NO_SUCH_ITEM, + GROUP_REF_NO_SUCH_ENTITY, + GROUP_REF_UNEXPECTED_TYPE, + IMPLICIT_DOWNCAST, + AMBIG_IMPLICIT_DOWNCAST, + /* express.c */ + BAIL_OUT, + SYNTAX, + REF_NONEXISTENT, + TILDE_EXPANSION_FAILED, + SCHEMA_NOT_IN_OWN_SCHEMA_FILE, + UNLABELLED_PARAM_TYPE, + FILE_UNREADABLE, + FILE_UNWRITABLE, + WARN_UNSUPPORTED_LANG_FEAT, + WARN_SMALL_REAL, + /* lexact.c */ + INCLUDE_FILE, + UNMATCHED_CLOSE_COMMENT, + UNMATCHED_OPEN_COMMENT, + UNTERMINATED_STRING, + ENCODED_STRING_BAD_DIGIT, + ENCODED_STRING_BAD_COUNT, + BAD_IDENTIFIER, + UNEXPECTED_CHARACTER, + NONASCII_CHAR, + /* linklist.c */ + EMPTY_LIST, + /* resolve.c */ + UNDEFINED, + UNDEFINED_ATTR, + UNDEFINED_TYPE, + UNDEFINED_SCHEMA, + UNKNOWN_ATTR_IN_ENTITY, + UNKNOWN_SUBTYPE, + UNKNOWN_SUPERTYPE, + CIRCULAR_REFERENCE, + SUBSUPER_LOOP, + SUBSUPER_CONTINUATION, + SELECT_LOOP, + SELECT_CONTINUATION, + SUPERTYPE_RESOLVE, + SUBTYPE_RESOLVE, + NOT_A_TYPE, + FUNCALL_NOT_A_FUNCTION, + UNDEFINED_FUNC, + EXPECTED_PROC, + NO_SUCH_PROCEDURE, + WRONG_ARG_COUNT, + QUERY_REQUIRES_AGGREGATE, + SELF_IS_UNKNOWN, + INVERSE_BAD_ENTITY, + INVERSE_BAD_ATTR, + MISSING_SUPERTYPE, + TYPE_IS_ENTITY, + AMBIGUOUS_ATTR, + AMBIGUOUS_GROUP, + OVERLOADED_ATTR, + REDECL_NO_SUCH_ATTR, + REDECL_NO_SUCH_SUPERTYPE, + MISSING_SELF, + FN_SKIP_BRANCH, + CASE_SKIP_LABEL, + UNIQUE_QUAL_REDECL, + /* type.c */ + CORRUPTED_TYPE, + UNDEFINED_TAG, + /* exppp.c */ + SELECT_EMPTY, +}; + +/*************/ +/* constants */ +/*************/ + +#define ERROR_none (Error)NULL +#define ERROR_MAX 100 + /************/ /* typedefs */ /************/ -typedef enum { - SEVERITY_WARNING = 0, - SEVERITY_ERROR = 1, - SEVERITY_EXIT = 2, - SEVERITY_DUMP = 3, - SEVERITY_MAX = 4 -} Severity; +enum Severity { + SEVERITY_WARNING = 0, + SEVERITY_ERROR, + SEVERITY_EXIT, + SEVERITY_DUMP, + SEVERITY_MAX +}; /***************************/ /* hidden type definitions */ /***************************/ -typedef struct Error_ { - bool enabled; - Severity severity; - char * message; - int serial; /* used to give each type of error a unique identifier */ -} * Error; +struct Error_ { + enum Severity severity; + const char *message; + const char *name; + bool override; +}; -typedef struct Error_Warning_ { - char * name; - struct Linked_List_ * errors; -} * Error_Warning; +typedef struct Error_ *Error; /****************/ /* modules used */ @@ -89,10 +172,6 @@ extern SC_EXPRESS_EXPORT const char * current_filename; extern SC_EXPRESS_EXPORT bool ERRORoccurred; -extern SC_EXPRESS_EXPORT Error experrc; -extern SC_EXPRESS_EXPORT Error ERROR_subordinate_failed; -extern SC_EXPRESS_EXPORT Error ERROR_syntax_expecting; - /* all of these are 1 if true, 0 if false switches */ /* for debugging fedex */ extern SC_EXPRESS_EXPORT int ERRORdebugging; @@ -101,52 +180,16 @@ extern SC_EXPRESS_EXPORT int malloc_debug_resolve; /* for debugging yacc/lex */ extern SC_EXPRESS_EXPORT int debug; -extern SC_EXPRESS_EXPORT struct Linked_List_ * ERRORwarnings; -extern SC_EXPRESS_EXPORT struct freelist_head ERROR_OPT_fl; - extern SC_EXPRESS_EXPORT void ( *ERRORusage_function )( void ); -/******************************/ -/* macro function definitions */ -/******************************/ - -#define ERROR_OPT_new() (struct Error_Warning_ *)MEM_new(&ERROR_OPT_fl) -#define ERROR_OPT_destroy(x) MEM_destroy(&ERROR_OPT_fl,(Freelist *)(Generic)x) - /***********************/ /* function prototypes */ /***********************/ -#if defined(__MSVC__) || defined(__BORLAND__) -extern SC_EXPRESS_EXPORT void ERROR_start_message_buffer PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void ERROR_flush_message_buffer PROTO( ( void ) ); -#endif - -/********************/ -/* Inline functions */ -/********************/ +extern SC_EXPRESS_EXPORT void ERROR_start_message_buffer( void ); +extern SC_EXPRESS_EXPORT void ERROR_flush_message_buffer( void ); -static_inline void ERRORdisable( Error error ) { - if( error != ERROR_none ) { - error->enabled = false; - } -} - -static_inline void ERRORenable( Error error ) { - if( error != ERROR_none ) { - error->enabled = true; - } -} - -static_inline bool ERRORis_enabled( Error error ) { - return error->enabled; -} - -static_inline void ERRORbuffer_messages( bool flag ) { -#if !defined(__MSVC__) && !defined(__BORLAND__) - extern void ERROR_start_message_buffer( void ), - ERROR_flush_message_buffer( void ); -#endif +static inline void ERRORbuffer_messages( bool flag ) { __ERROR_buffer_errors = flag; if( __ERROR_buffer_errors ) { ERROR_start_message_buffer(); @@ -155,44 +198,34 @@ static_inline void ERRORbuffer_messages( bool flag ) { } } -static_inline void ERRORflush_messages( void ) { -#if !defined(__MSVC__) && !defined(__BORLAND__) - extern void ERROR_start_message_buffer( void ), - ERROR_flush_message_buffer( void ); -#endif - +static inline void ERRORflush_messages( void ) { if( __ERROR_buffer_errors ) { ERROR_flush_message_buffer(); ERROR_start_message_buffer(); } } + /***********************/ /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT void ERRORinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void ERRORinitialize_after_LIST PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void ERRORcleanup PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void ERRORnospace PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void ERRORabort PROTO( ( int ) ); -extern SC_EXPRESS_EXPORT Error ERRORcreate PROTO( ( char *, Severity ) ); -extern SC_EXPRESS_EXPORT void ERRORreport PROTO( ( Error, ... ) ); -extern SC_EXPRESS_EXPORT void ERRORdestroy PROTO( ( Error ) ); +extern SC_EXPRESS_EXPORT void ERRORinitialize( void ); +extern SC_EXPRESS_EXPORT void ERRORcleanup( void ); +extern SC_EXPRESS_EXPORT void ERRORnospace( void ); +extern SC_EXPRESS_EXPORT void ERRORabort( int ); +extern SC_EXPRESS_EXPORT void ERRORreport( enum ErrorCode, ... ); struct Symbol_; /* mention Symbol to avoid warning on following line */ -extern SC_EXPRESS_EXPORT void ERRORreport_with_symbol PROTO( ( Error, struct Symbol_ *, ... ) ); -extern SC_EXPRESS_EXPORT void ERRORreport_with_line PROTO( ( Error, int, ... ) ); - -#if !defined(__MSVC__) && !defined(__BORLAND__) -extern SC_EXPRESS_EXPORT void ERROR_start_message_buffer PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void ERROR_flush_message_buffer PROTO( ( void ) ); -#endif - -extern SC_EXPRESS_EXPORT void ERRORcreate_warning PROTO( ( char *, Error ) ); -extern SC_EXPRESS_EXPORT void ERRORset_warning PROTO( ( char *, int ) ); -extern SC_EXPRESS_EXPORT void ERRORset_all_warnings PROTO( ( int ) ); -extern SC_EXPRESS_EXPORT void ERRORsafe PROTO( ( jmp_buf env ) ); -extern SC_EXPRESS_EXPORT void ERRORunsafe PROTO( ( void ) ); +extern SC_EXPRESS_EXPORT void ERRORreport_with_symbol( enum ErrorCode, struct Symbol_ *, ... ); +extern SC_EXPRESS_EXPORT void ERRORreport_with_line( enum ErrorCode, int, ... ); + +extern SC_EXPRESS_EXPORT void ERRORset_warning( char *, bool ); +extern SC_EXPRESS_EXPORT void ERRORset_all_warnings( bool ); +extern SC_EXPRESS_EXPORT void ERRORsafe( jmp_buf env ); +extern SC_EXPRESS_EXPORT void ERRORunsafe( void ); + +extern SC_EXPRESS_EXPORT char * ERRORget_warnings_help(const char* prefix, const char *eol); +extern SC_EXPRESS_EXPORT bool ERRORis_enabled(enum ErrorCode errnum); #endif /* ERROR_H */ diff --git a/include/express/expbasic.h b/include/express/expbasic.h index 15006e379..63ab6e291 100644 --- a/include/express/expbasic.h +++ b/include/express/expbasic.h @@ -46,11 +46,7 @@ typedef enum { Lfalse, Lunknown, Ltrue } Logical; /* typedef ... Binary; done below because String not defined yet */ #ifndef _CLIENTDATA -# ifdef __STDC__ typedef void * ClientData; -# else -typedef int * ClientData; -# endif /* __STDC__ */ #define _CLIENTDATA #endif @@ -58,7 +54,7 @@ typedef int * ClientData; /* packages used throughout */ /****************************/ -#include "memory.h" +#include "alloc.h" typedef struct Scope_ * Type; typedef struct Scope_ * Scope; diff --git a/include/express/expr.h b/include/express/expr.h index 56cb8e186..57191d5b6 100644 --- a/include/express/expr.h +++ b/include/express/expr.h @@ -178,7 +178,7 @@ struct Expression_ { /** indexed by the op enumeration values */ struct EXPop_entry { char * token; /**< literal token, e.g., "<>" */ - Type( *resolve ) PROTO( ( Expression, struct Scope_ * ) ); + Type( *resolve )( Expression, struct Scope_ * ); }; /********************/ @@ -193,11 +193,6 @@ extern SC_EXPRESS_EXPORT Expression LITERAL_PI; extern SC_EXPRESS_EXPORT Expression LITERAL_ZERO; extern SC_EXPRESS_EXPORT Expression LITERAL_ONE; -extern SC_EXPRESS_EXPORT Error ERROR_bad_qualification; -extern SC_EXPRESS_EXPORT Error ERROR_integer_expression_expected; -extern SC_EXPRESS_EXPORT Error ERROR_implicit_downcast; -extern SC_EXPRESS_EXPORT Error ERROR_ambig_implicit_downcast; - extern SC_EXPRESS_EXPORT struct freelist_head EXP_fl; extern SC_EXPRESS_EXPORT struct freelist_head OP_fl; extern SC_EXPRESS_EXPORT struct freelist_head QUERY_fl; @@ -207,14 +202,14 @@ extern SC_EXPRESS_EXPORT struct freelist_head QUAL_ATTR_fl; /* macro function definitions */ /******************************/ -#define EXP_new() (struct Expression_ *)MEM_new(&EXP_fl) -#define EXP_destroy(x) MEM_destroy(&EXP_fl,(Freelist *)(Generic)x) -#define OP_new() (struct Op_Subexpression *)MEM_new(&OP_fl) -#define OP_destroy(x) MEM_destroy(&OP_fl,(Freelist *)(Generic)x) -#define QUERY_new() (struct Query_ *)MEM_new(&QUERY_fl) -#define QUERY_destroy(x) MEM_destroy(&QUERY_fl,(Freelist *)(Generic)x) -#define QUAL_ATTR_new() (struct Qualified_Attr *)MEM_new(&QUAL_ATTR_fl) -#define QUAL_ATTR_destroy(x) MEM_destroy(&QUAL_ATTR_fl,(Freelist *)(Generic)x) +#define EXP_new() (struct Expression_ *)ALLOC_new(&EXP_fl) +#define EXP_destroy(x) ALLOC_destroy(&EXP_fl,(Freelist *)x) +#define OP_new() (struct Op_Subexpression *)ALLOC_new(&OP_fl) +#define OP_destroy(x) ALLOC_destroy(&OP_fl,(Freelist *)x) +#define QUERY_new() (struct Query_ *)ALLOC_new(&QUERY_fl) +#define QUERY_destroy(x) ALLOC_destroy(&QUERY_fl,(Freelist *)x) +#define QUAL_ATTR_new() (struct Qualified_Attr *)ALLOC_new(&QUAL_ATTR_fl) +#define QUAL_ATTR_destroy(x) ALLOC_destroy(&QUAL_ATTR_fl,(Freelist *)x) #define EXPget_name(e) ((e)->symbol.name) #define ENUMget_name(e) ((e)->symbol.name) @@ -254,16 +249,18 @@ extern SC_EXPRESS_EXPORT struct freelist_head QUAL_ATTR_fl; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT Expression EXPcreate PROTO( ( Type ) ); -extern SC_EXPRESS_EXPORT Expression EXPcreate_simple PROTO( ( Type ) ); -extern SC_EXPRESS_EXPORT Expression EXPcreate_from_symbol PROTO( ( Type, Symbol * ) ); -extern SC_EXPRESS_EXPORT Expression UN_EXPcreate PROTO( ( Op_Code, Expression ) ); -extern SC_EXPRESS_EXPORT Expression BIN_EXPcreate PROTO( ( Op_Code, Expression, Expression ) ); -extern SC_EXPRESS_EXPORT Expression TERN_EXPcreate PROTO( ( Op_Code, Expression, Expression, Expression ) ); -extern SC_EXPRESS_EXPORT Expression QUERYcreate PROTO( ( Symbol *, Expression ) ); -extern SC_EXPRESS_EXPORT void EXPinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void EXPcleanup PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT Type EXPtype PROTO( ( Expression, struct Scope_ * ) ); -extern SC_EXPRESS_EXPORT int EXPget_integer_value PROTO( ( Expression ) ); +extern SC_EXPRESS_EXPORT Expression EXPcreate( Type ); +extern SC_EXPRESS_EXPORT Expression EXPcreate_simple( Type ); +extern SC_EXPRESS_EXPORT Expression EXPcreate_from_symbol( Type, Symbol * ); +extern SC_EXPRESS_EXPORT Expression UN_EXPcreate( Op_Code, Expression ); +extern SC_EXPRESS_EXPORT Expression BIN_EXPcreate( Op_Code, Expression, Expression ); +extern SC_EXPRESS_EXPORT Expression TERN_EXPcreate( Op_Code, Expression, Expression, Expression ); +extern SC_EXPRESS_EXPORT Expression QUERYcreate( Symbol *, Expression ); +extern SC_EXPRESS_EXPORT void EXPinitialize( void ); +extern SC_EXPRESS_EXPORT void EXPcleanup( void ); +extern SC_EXPRESS_EXPORT Type EXPtype( Expression, struct Scope_ * ); +extern SC_EXPRESS_EXPORT int EXPget_integer_value( Expression ); + +Type EXPresolve_op_dot( Expression, Scope ); #endif /*EXPRESSION_H*/ diff --git a/include/express/express.h b/include/express/express.h index f04beb1d3..e849ae56a 100644 --- a/include/express/express.h +++ b/include/express/express.h @@ -92,26 +92,18 @@ extern SC_EXPRESS_EXPORT char * input_filename; extern SC_EXPRESS_EXPORT Linked_List EXPRESS_path; extern SC_EXPRESS_EXPORT int EXPRESSpass; -extern SC_EXPRESS_EXPORT void ( *EXPRESSinit_args ) PROTO( ( int, char ** ) ); -extern SC_EXPRESS_EXPORT void ( *EXPRESSinit_parse ) PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT int ( *EXPRESSfail ) PROTO( ( Express ) ); -extern SC_EXPRESS_EXPORT int ( *EXPRESSsucceed ) PROTO( ( Express ) ); -extern SC_EXPRESS_EXPORT void ( *EXPRESSbackend ) PROTO( ( Express ) ); +extern SC_EXPRESS_EXPORT void ( *EXPRESSinit_args )( int, char ** ); +extern SC_EXPRESS_EXPORT void ( *EXPRESSinit_parse )( void ); +extern SC_EXPRESS_EXPORT int ( *EXPRESSfail )( Express ); +extern SC_EXPRESS_EXPORT int ( *EXPRESSsucceed )( Express ); +extern SC_EXPRESS_EXPORT void ( *EXPRESSbackend )( Express ); extern SC_EXPRESS_EXPORT char * EXPRESSprogram_name; extern char EXPRESSgetopt_options[]; /* initialized elsewhere */ -extern SC_EXPRESS_EXPORT int ( *EXPRESSgetopt ) PROTO( ( int, char * ) ); +extern SC_EXPRESS_EXPORT int ( *EXPRESSgetopt )( int, char * ); extern SC_EXPRESS_EXPORT bool EXPRESSignore_duplicate_schemas; extern SC_EXPRESS_EXPORT Dictionary EXPRESSbuiltins; /* procedures/functions */ -extern SC_EXPRESS_EXPORT Error ERROR_bail_out; -extern SC_EXPRESS_EXPORT Error ERROR_syntax; -extern SC_EXPRESS_EXPORT Error ERROR_unlabelled_param_type; -extern SC_EXPRESS_EXPORT Error ERROR_file_unreadable; -extern SC_EXPRESS_EXPORT Error ERROR_file_unwriteable; -extern SC_EXPRESS_EXPORT Error ERROR_warn_unsupported_lang_feat; -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; @@ -128,15 +120,15 @@ extern SC_EXPRESS_EXPORT struct Scope_ * FUNC_USEDIN; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT Express EXPRESScreate PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void EXPRESSdestroy PROTO( ( Express ) ); -extern SC_EXPRESS_EXPORT void EXPRESSparse PROTO( ( Express, FILE *, char * ) ); -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 Express EXPRESScreate( void ); +extern SC_EXPRESS_EXPORT void EXPRESSdestroy( Express ); +extern SC_EXPRESS_EXPORT void EXPRESSparse( Express, FILE *, char * ); +extern SC_EXPRESS_EXPORT void EXPRESSinitialize( void ); +extern SC_EXPRESS_EXPORT void EXPRESScleanup( void ); +extern SC_EXPRESS_EXPORT void EXPRESSresolve( Express ); extern SC_EXPRESS_EXPORT int EXPRESS_fail( Express model ); extern SC_EXPRESS_EXPORT int EXPRESS_succeed( Express model ); -extern void EXPRESSinit_init PROTO( ( void ) ); +extern void EXPRESSinit_init( void ); extern SC_EXPRESS_EXPORT void build_complex( Express ); #endif /*EXPRESS_H*/ diff --git a/include/express/factory.h b/include/express/factory.h new file mode 100644 index 000000000..4942256fe --- /dev/null +++ b/include/express/factory.h @@ -0,0 +1,8 @@ +#ifndef __FACTORY_H_ +#define __FACTORY_H_ + +#include "sc_export.h" + +SC_EXPRESS_EXPORT void FACTORYinitialize(); + +#endif /* __FACTORY_H_ */ diff --git a/include/express/hash.h b/include/express/hash.h index c9e7782c1..c5d1dfffe 100644 --- a/include/express/hash.h +++ b/include/express/hash.h @@ -101,7 +101,7 @@ /*****************/ #include -#include "memory.h" +#include "alloc.h" /************/ /* typedefs */ @@ -183,23 +183,22 @@ This change only seems to have affected hash.h and hash.c #define DIV(x,y) ((x) >> (y)) #define MOD(x,y) ((x) & ((y)-1)) -#define HASH_Table_new() (struct Hash_Table_ *)MEM_new(&HASH_Table_fl) -#define HASH_Table_destroy(x) MEM_destroy(&HASH_Table_fl,(Freelist *)(Generic)x) -#define HASH_Element_new() (struct Element_ *)MEM_new(&HASH_Element_fl) -#define HASH_Element_destroy(x) MEM_destroy(&HASH_Element_fl,(Freelist *)(char *)x) - +#define HASH_Table_new() (struct Hash_Table_ *)ALLOC_new(&HASH_Table_fl) +#define HASH_Table_destroy(x) ALLOC_destroy(&HASH_Table_fl,(Freelist *)x) +#define HASH_Element_new() (struct Element_ *)ALLOC_new(&HASH_Element_fl) +#define HASH_Element_destroy(x) ALLOC_destroy(&HASH_Element_fl,(Freelist *)(char *)x) /***********************/ /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT void HASHinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT Hash_Table HASHcreate PROTO( ( unsigned ) ); -extern SC_EXPRESS_EXPORT Hash_Table HASHcopy PROTO( ( Hash_Table ) ); -extern SC_EXPRESS_EXPORT void HASHdestroy PROTO( ( Hash_Table ) ); -extern SC_EXPRESS_EXPORT Element HASHsearch PROTO( ( Hash_Table, Element, Action ) ); -extern SC_EXPRESS_EXPORT void HASHlistinit PROTO( ( Hash_Table, HashEntry * ) ); -extern SC_EXPRESS_EXPORT void HASHlistinit_by_type PROTO( ( Hash_Table, HashEntry *, char ) ); -extern SC_EXPRESS_EXPORT Element HASHlist PROTO( ( HashEntry * ) ); +extern SC_EXPRESS_EXPORT void HASHinitialize( void ); +extern SC_EXPRESS_EXPORT Hash_Table HASHcreate( unsigned ); +extern SC_EXPRESS_EXPORT Hash_Table HASHcopy( Hash_Table ); +extern SC_EXPRESS_EXPORT void HASHdestroy( Hash_Table ); +extern SC_EXPRESS_EXPORT Element HASHsearch( Hash_Table, Element, Action ); +extern SC_EXPRESS_EXPORT void HASHlistinit( Hash_Table, HashEntry * ); +extern SC_EXPRESS_EXPORT void HASHlistinit_by_type( Hash_Table, HashEntry *, char ); +extern SC_EXPRESS_EXPORT Element HASHlist( HashEntry * ); #endif /*HASH_H*/ diff --git a/include/express/lexact.h b/include/express/lexact.h index 40bc47539..9e9ac3559 100644 --- a/include/express/lexact.h +++ b/include/express/lexact.h @@ -72,16 +72,6 @@ extern SC_EXPRESS_EXPORT Scan_Buffer SCAN_buffers[SCAN_NESTING_DEPTH]; extern SC_EXPRESS_EXPORT int SCAN_current_buffer; extern SC_EXPRESS_EXPORT char * SCANcurrent; -extern SC_EXPRESS_EXPORT Error ERROR_include_file; -extern SC_EXPRESS_EXPORT Error ERROR_unmatched_close_comment; -extern SC_EXPRESS_EXPORT Error ERROR_unmatched_open_comment; -extern SC_EXPRESS_EXPORT Error ERROR_unterminated_string; -extern SC_EXPRESS_EXPORT Error ERROR_encoded_string_bad_digit; -extern SC_EXPRESS_EXPORT Error ERROR_encoded_string_bad_count; -extern SC_EXPRESS_EXPORT Error ERROR_bad_identifier; -extern SC_EXPRESS_EXPORT Error ERROR_unexpected_character; -extern SC_EXPRESS_EXPORT Error ERROR_nonascii_char; - /******************************/ /* macro function definitions */ /******************************/ @@ -95,26 +85,30 @@ extern SC_EXPRESS_EXPORT Error ERROR_nonascii_char; # define SCANtext_ready (*SCANcurrent != '\0') #endif +#ifndef static_inline +# define static_inline static inline +#endif + /***********************/ /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT void SCANinitialize PROTO( ( void ) ); +extern SC_EXPRESS_EXPORT void SCANinitialize( void ); extern SC_EXPRESS_EXPORT void SCANcleanup( void ); -extern SC_EXPRESS_EXPORT int SCANprocess_real_literal PROTO( ( const char * ) ); -extern SC_EXPRESS_EXPORT int SCANprocess_integer_literal PROTO( ( const char * ) ); -extern SC_EXPRESS_EXPORT int SCANprocess_binary_literal PROTO( ( const char * ) ); -extern SC_EXPRESS_EXPORT int SCANprocess_logical_literal PROTO( ( char * ) ); -extern SC_EXPRESS_EXPORT int SCANprocess_identifier_or_keyword PROTO( ( const char * ) ); -extern SC_EXPRESS_EXPORT int SCANprocess_string PROTO( ( const char * ) ); -extern SC_EXPRESS_EXPORT int SCANprocess_encoded_string PROTO( ( const char * ) ); -extern SC_EXPRESS_EXPORT int SCANprocess_semicolon PROTO( ( const char *, int ) ); -extern SC_EXPRESS_EXPORT void SCANsave_comment PROTO( ( const char * ) ); -extern SC_EXPRESS_EXPORT bool SCANread PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void SCANinclude_file PROTO( ( char * ) ); - SC_EXPRESS_EXPORT void SCANlowerize PROTO( ( char * ) ); - SC_EXPRESS_EXPORT void SCANupperize PROTO( ( char * ) ); -extern SC_EXPRESS_EXPORT char * SCANstrdup PROTO( ( const char * ) ); -extern SC_EXPRESS_EXPORT long SCANtell PROTO( ( void ) ); +extern SC_EXPRESS_EXPORT int SCANprocess_real_literal( const char * ); +extern SC_EXPRESS_EXPORT int SCANprocess_integer_literal( const char * ); +extern SC_EXPRESS_EXPORT int SCANprocess_binary_literal( const char * ); +extern SC_EXPRESS_EXPORT int SCANprocess_logical_literal( char * ); +extern SC_EXPRESS_EXPORT int SCANprocess_identifier_or_keyword( const char * ); +extern SC_EXPRESS_EXPORT int SCANprocess_string( const char * ); +extern SC_EXPRESS_EXPORT int SCANprocess_encoded_string( const char * ); +extern SC_EXPRESS_EXPORT int SCANprocess_semicolon( const char *, int ); +extern SC_EXPRESS_EXPORT void SCANsave_comment( const char * ); +extern SC_EXPRESS_EXPORT bool SCANread( void ); +extern SC_EXPRESS_EXPORT void SCANinclude_file( char * ); + SC_EXPRESS_EXPORT void SCANlowerize( char * ); + SC_EXPRESS_EXPORT void SCANupperize( char * ); +extern SC_EXPRESS_EXPORT char * SCANstrdup( const char * ); +extern SC_EXPRESS_EXPORT long SCANtell( void ); #endif /* LEX_ACTIONS_H */ diff --git a/include/express/linklist.h b/include/express/linklist.h index 01581eb14..76c31a461 100644 --- a/include/express/linklist.h +++ b/include/express/linklist.h @@ -38,7 +38,7 @@ #include #include "basic.h" -#include "memory.h" +#include "alloc.h" /************/ /* typedefs */ @@ -59,7 +59,7 @@ typedef struct Linked_List_ * Linked_List; typedef struct Link_ { struct Link_ * next; struct Link_ * prev; - Generic data; + void *data; } * Link; struct Linked_List_ { @@ -70,7 +70,6 @@ struct Linked_List_ { /* global variables */ /********************/ -extern SC_EXPRESS_EXPORT Error ERROR_empty_list; extern SC_EXPRESS_EXPORT struct freelist_head LINK_fl; extern SC_EXPRESS_EXPORT struct freelist_head LIST_fl; @@ -78,10 +77,10 @@ extern SC_EXPRESS_EXPORT struct freelist_head LIST_fl; /* macro function definitions */ /******************************/ -#define LINK_new() (struct Link_ *)MEM_new(&LINK_fl) -#define LINK_destroy(x) MEM_destroy(&LINK_fl,(Freelist *)(Generic)x) -#define LIST_new() (struct Linked_List_ *)MEM_new(&LIST_fl) -#define LIST_destroy(x) MEM_destroy(&LIST_fl,(Freelist *)(Generic)x) +#define LINK_new() (struct Link_ *)ALLOC_new(&LINK_fl) +#define LINK_destroy(x) ALLOC_destroy(&LINK_fl,(Freelist *)x) +#define LIST_new() (struct Linked_List_ *)ALLOC_new(&LIST_fl) +#define LIST_destroy(x) ALLOC_destroy(&LIST_fl,(Freelist *)x) /** accessing links */ #define LINKdata(link) (link)->data @@ -125,22 +124,22 @@ extern SC_EXPRESS_EXPORT struct freelist_head LIST_fl; /* function prototypes */ /***********************/ -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 ) ); -extern SC_EXPRESS_EXPORT Generic LISTadd_before PROTO( ( Linked_List, Link, Generic ) ); -extern SC_EXPRESS_EXPORT Generic LISTremove_first PROTO( ( Linked_List ) ); -extern SC_EXPRESS_EXPORT Generic LISTget_first PROTO( ( Linked_List ) ); -extern SC_EXPRESS_EXPORT Generic LISTget_second PROTO( ( Linked_List ) ); -extern SC_EXPRESS_EXPORT Generic LISTget_nth PROTO( ( Linked_List, int ) ); -extern SC_EXPRESS_EXPORT void LISTfree PROTO( ( Linked_List ) ); -extern SC_EXPRESS_EXPORT int LISTget_length PROTO( ( Linked_List ) ); +extern SC_EXPRESS_EXPORT void LISTinitialize( void ); +extern SC_EXPRESS_EXPORT void LISTcleanup( void ); +extern SC_EXPRESS_EXPORT Linked_List LISTcreate( void ); +extern SC_EXPRESS_EXPORT Linked_List LISTcopy( Linked_List ); +extern SC_EXPRESS_EXPORT void LISTsort( Linked_List, int (*comp)(void*, void*) ); +extern SC_EXPRESS_EXPORT void LISTswap( Link, Link ); +extern SC_EXPRESS_EXPORT void * LISTadd_first( Linked_List, void * ); +extern SC_EXPRESS_EXPORT void * LISTadd_last( Linked_List, void * ); +extern SC_EXPRESS_EXPORT void * LISTadd_after( Linked_List, Link, void * ); +extern SC_EXPRESS_EXPORT void * LISTadd_before( Linked_List, Link, void * ); +extern SC_EXPRESS_EXPORT void * LISTremove_first( Linked_List ); +extern SC_EXPRESS_EXPORT void * LISTget_first( Linked_List ); +extern SC_EXPRESS_EXPORT void * LISTget_second( Linked_List ); +extern SC_EXPRESS_EXPORT void * LISTget_nth( Linked_List, int ); +extern SC_EXPRESS_EXPORT void LISTfree( Linked_List ); +extern SC_EXPRESS_EXPORT int LISTget_length( Linked_List ); extern SC_EXPRESS_EXPORT bool LISTempty( Linked_List list ); #endif /*LINKED_LIST_H*/ diff --git a/include/express/memory.h b/include/express/memory.h index 305664739..3d1e58c74 100644 --- a/include/express/memory.h +++ b/include/express/memory.h @@ -1,85 +1,8 @@ -#ifndef MEMORY_H -#define MEMORY_H +#ifndef __MEMORY_H +#define __MEMORY_H -/* - * This work was supported by the United States Government, and is - * not subject to copyright. - * - * $Log: memory.h,v $ - * Revision 1.5 1997/01/21 19:17:11 dar - * made C++ compatible - * - * Revision 1.4 1993/10/15 18:49:23 libes - * CADDETC certified - * - * Revision 1.3 1993/02/22 21:41:13 libes - * ANSI compat - * - * Revision 1.2 1992/08/18 17:15:40 libes - * rm'd extraneous error messages - * - * Revision 1.1 1992/05/28 03:56:02 libes - * Initial revision - */ - -#include "basic.h" - -/*****************/ -/* packages used */ -/*****************/ - -#include - -/** \file memory.h - defs for fixed size block memory allocator */ - -typedef long Align; - -union freelist { - union freelist * next; /**< next block on freelist */ - char memory; /**< user data */ - Align aligner; /**< force alignment of blocks */ -}; - -typedef union freelist Freelist; - -struct freelist_head { - int size_elt; /**< size of a single elt */ -#ifndef NOSTAT - int alloc; /**< # of allocations */ - int dealloc; - int create; /**< number of calls to create a new freelist */ - Generic max; /**< end of freelist */ -#endif - int size; /**< size of a single elt incl. next ptr */ - int bytes; /**< if we run out, allocate memory by this many bytes */ - Freelist * freelist; -#ifdef SPACE_PROFILE - int count; -#endif -}; - -char * nnew(); - -#include "error.h" - -/***********************************************/ -/* space allocation macros with error package: */ -/***********************************************/ - -extern SC_EXPRESS_EXPORT int yylineno; - -/** CALLOC grabs and initializes to all 0s space for the indicated - * number of instances of the indicated type */ -#define CALLOC(ptr, num, type) \ - if (((ptr) = (type*)calloc((num), (unsigned)sizeof(type)))==NULL) { \ - fprintf(stderr,"fedex: out of space");\ - } else {} - -SC_EXPRESS_EXPORT void _MEMinitialize PROTO( ( void ) ); -SC_EXPRESS_EXPORT void MEMinitialize PROTO( ( struct freelist_head * flh, unsigned int size, int alloc1, int alloc2 ) ); -SC_EXPRESS_EXPORT void MEM_destroy PROTO( ( struct freelist_head *, Freelist * ) ); -SC_EXPRESS_EXPORT Generic MEM_new PROTO( ( struct freelist_head * ) ); - -#endif /* MEMORY_H */ +#include "sc_export.h" +SC_EXPRESS_EXPORT void MEMORYinitialize(); +#endif // __MEMORY_H diff --git a/include/express/object.h b/include/express/object.h index d0f5052bf..15e4a435f 100644 --- a/include/express/object.h +++ b/include/express/object.h @@ -68,7 +68,7 @@ /***************************/ struct Object { - struct Symbol_ * ( *get_symbol )(); + struct Symbol_ * ( *get_symbol )( void * ); char * type; /**< should complete the phrase "X is ..." - i.e., "an entity", "a type", "of unknown type" */ int bits; /**< a bitwise selector of a type, i.e. OBJ_XX_BITS */ }; @@ -81,7 +81,7 @@ struct Object { /* global variables */ /********************/ -extern SC_EXPRESS_EXPORT struct Object * OBJ; +extern SC_EXPRESS_EXPORT struct Object OBJ[]; /******************************/ /* macro function definitions */ @@ -97,9 +97,4 @@ extern SC_EXPRESS_EXPORT struct Object * OBJ; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT void OBJinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void OBJcleanup PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void OBJcreate PROTO( ( char, struct Symbol_ * ( * )( Generic ), char *, int ) ); -extern SC_EXPRESS_EXPORT Symbol * UNK_get_symbol PROTO( ( Generic x ) ); - #endif /*OBJECT_H*/ diff --git a/include/express/resolve.h b/include/express/resolve.h index c9169d55c..7eca8aa07 100644 --- a/include/express/resolve.h +++ b/include/express/resolve.h @@ -47,19 +47,6 @@ extern SC_EXPRESS_EXPORT int print_objects_while_running; -extern SC_EXPRESS_EXPORT Error ERROR_undefined_attribute; -extern SC_EXPRESS_EXPORT Error ERROR_undefined_type; -extern SC_EXPRESS_EXPORT Error ERROR_undefined_schema; -extern SC_EXPRESS_EXPORT Error ERROR_unknown_attr_in_entity; -extern SC_EXPRESS_EXPORT Error ERROR_unknown_subtype; -extern SC_EXPRESS_EXPORT Error ERROR_unknown_supertype; -extern SC_EXPRESS_EXPORT Error ERROR_circular_reference; -extern SC_EXPRESS_EXPORT Error ERROR_ambiguous_attribute; -extern SC_EXPRESS_EXPORT Error ERROR_ambiguous_group; - -extern SC_EXPRESS_EXPORT Error WARNING_case_skip_label; -extern SC_EXPRESS_EXPORT Error WARNING_fn_skip_branch; - /* macros */ /* cheaper doing the check here, then inside the function call. Return */ @@ -73,14 +60,29 @@ extern SC_EXPRESS_EXPORT Error WARNING_fn_skip_branch; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT void RESOLVEinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void RESOLVEcleanup PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void SCOPEresolve_expressions_statements PROTO( ( Scope ) ); -extern SC_EXPRESS_EXPORT void SCOPEresolve_subsupers PROTO( ( Scope ) ); -extern SC_EXPRESS_EXPORT void SCOPEresolve_types PROTO( ( Scope ) ); -extern SC_EXPRESS_EXPORT void TYPE_resolve PROTO( ( Type * ) ); -extern SC_EXPRESS_EXPORT void EXP_resolve PROTO( ( Expression, Scope, Type ) ); -extern SC_EXPRESS_EXPORT void ALGresolve PROTO( ( Scope ) ); -extern SC_EXPRESS_EXPORT void SCHEMAresolve PROTO( ( Scope ) ); +extern SC_EXPRESS_EXPORT void RESOLVEinitialize( void ); +extern SC_EXPRESS_EXPORT void RESOLVEcleanup( void ); +extern SC_EXPRESS_EXPORT void SCOPEresolve_expressions_statements( Scope ); +extern SC_EXPRESS_EXPORT void SCOPEresolve_subsupers( Scope ); +extern SC_EXPRESS_EXPORT void SCOPEresolve_types( Scope ); +extern SC_EXPRESS_EXPORT void TYPE_resolve( Type * ); +extern SC_EXPRESS_EXPORT void EXP_resolve( Expression, Scope, Type ); +extern SC_EXPRESS_EXPORT void ALGresolve( Scope ); +extern SC_EXPRESS_EXPORT void SCHEMAresolve( Scope ); +extern SC_EXPRESS_EXPORT void RENAMEresolve( Rename *, Schema ); + +/* + * for unit tests, no extern / export + */ +void VAR_resolve_expressions( Variable, Entity ); +void ENTITYresolve_subtypes( Schema ); +void ENTITYresolve_supertypes( Entity ); +void ENTITYresolve_expressions( Entity e ); +void ALGresolve_expressions_statements( Scope, Linked_List ); +int WHEREresolve( Linked_List, Scope, int ); +void TYPEresolve_expressions( Type, Scope ); +void STMTresolve( Statement, Scope ); +void STMTlist_resolve( Linked_List, Scope ); +int ENTITYresolve_subtype_expression( Expression, Entity, Linked_List * ); #endif /*RESOLVE_H*/ diff --git a/include/express/schema.h b/include/express/schema.h index 309d75f6e..1d2ce5c4b 100644 --- a/include/express/schema.h +++ b/include/express/schema.h @@ -76,7 +76,7 @@ typedef struct Rename { Schema schema; struct Symbol_ * old; struct Symbol_ * nnew; - Generic object; /**< once object has been looked up */ + void *object; /**< once object has been looked up */ char type; /**< drat, need to remember this once renames have been * resolved to avoid looking them up in the dictionary again */ enum rename_type rename_type; @@ -88,7 +88,7 @@ struct Schema_ { Linked_List reflist; Linked_List uselist; /** \var refdict, usedict - * dictionarys into which are entered renames for each specific + * dictionaries into which are entered renames for each specific * object specified in a rename clause (even if it uses the same * name */ Dictionary refdict; @@ -117,12 +117,12 @@ extern SC_EXPRESS_EXPORT int __SCOPE_search_id; #define SCHEMAget_name(schema) SCOPEget_name(schema) #define SCHEMAget_symbol(schema) SCOPEget_symbol(schema) -#define REN_new() (struct Rename *)MEM_new(&REN_fl) -#define REN_destroy(x) MEM_destroy(&REN_fl,(Freelist *)(Generic)x) -#define SCOPE_new() (struct Scope_ *)MEM_new(&SCOPE_fl) -#define SCOPE_destroy(x) MEM_destroy(&SCOPE_fl,(Freelist *)(Generic)x) -#define SCHEMA_new() (struct Schema_ *)MEM_new(&SCHEMA_fl) -#define SCHEMA_destroy(x) MEM_destroy(&SCHEMA_fl,(Freelist *)(Generic)x) +#define REN_new() (struct Rename *)ALLOC_new(&REN_fl) +#define REN_destroy(x) ALLOC_destroy(&REN_fl,(Freelist *)x) +#define SCOPE_new() (struct Scope_ *)ALLOC_new(&SCOPE_fl) +#define SCOPE_destroy(x) ALLOC_destroy(&SCOPE_fl,(Freelist *)x) +#define SCHEMA_new() (struct Schema_ *)ALLOC_new(&SCHEMA_fl) +#define SCHEMA_destroy(x) ALLOC_destroy(&SCHEMA_fl,(Freelist *)x) /* the following is simply to make the resulting code easier to read */ /* otherwise, you'd see "entity->superscope" even when you KNOW */ @@ -133,20 +133,22 @@ extern SC_EXPRESS_EXPORT int __SCOPE_search_id; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT Variable VARfind PROTO( ( Scope, char *, int ) ); -extern SC_EXPRESS_EXPORT Schema SCHEMAcreate PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void SCHEMAinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void SCHEMAadd_use PROTO( ( Schema, Symbol *, Symbol *, Symbol * ) ); -extern SC_EXPRESS_EXPORT void SCHEMAadd_reference PROTO( ( Schema, Symbol *, Symbol *, Symbol * ) ); -extern SC_EXPRESS_EXPORT void SCHEMAdefine_use PROTO( ( Schema, Rename * ) ); -extern SC_EXPRESS_EXPORT void SCHEMAdefine_reference PROTO( ( Schema, Rename * ) ); -extern SC_EXPRESS_EXPORT Generic SCHEMAfind PROTO( ( Schema, char * name, int search_refs ) ); -extern SC_EXPRESS_EXPORT Scope SCOPEcreate PROTO( ( char ) ); -extern SC_EXPRESS_EXPORT Scope SCOPEcreate_tiny PROTO( ( char ) ); -extern SC_EXPRESS_EXPORT Scope SCOPEcreate_nostab PROTO( ( char ) ); -extern SC_EXPRESS_EXPORT void SCOPEdestroy PROTO( ( Scope ) ); -extern SC_EXPRESS_EXPORT Linked_List SCHEMAget_entities_use PROTO( ( Scope ) ); -extern SC_EXPRESS_EXPORT Linked_List SCHEMAget_entities_ref PROTO( ( Scope ) ); +extern SC_EXPRESS_EXPORT Variable VARfind( Scope, char *, int ); +extern SC_EXPRESS_EXPORT Schema SCHEMAcreate( void ); +extern SC_EXPRESS_EXPORT void SCHEMAinitialize( void ); +extern SC_EXPRESS_EXPORT void SCHEMAadd_use( Schema, Symbol *, Symbol *, Symbol * ); +extern SC_EXPRESS_EXPORT void SCHEMAadd_reference( Schema, Symbol *, Symbol *, Symbol * ); +extern SC_EXPRESS_EXPORT void SCHEMAdefine_use( Schema, Rename * ); +extern SC_EXPRESS_EXPORT void SCHEMAdefine_reference( Schema, Rename * ); +extern SC_EXPRESS_EXPORT void * SCHEMAfind( Schema, char * name, int search_refs ); +extern SC_EXPRESS_EXPORT Scope SCOPEcreate( char ); +extern SC_EXPRESS_EXPORT Scope SCOPEcreate_tiny( char ); +extern SC_EXPRESS_EXPORT Scope SCOPEcreate_nostab( char ); +extern SC_EXPRESS_EXPORT void SCOPEdestroy( Scope ); +extern SC_EXPRESS_EXPORT Linked_List SCHEMAget_entities_use( Scope ); +extern SC_EXPRESS_EXPORT Linked_List SCHEMAget_entities_ref( Scope ); + +void SCHEMA_get_entities_ref( Scope, Linked_List ); #endif /* SCHEMA_H */ diff --git a/include/express/scope.h b/include/express/scope.h index c087fc035..8f16fafbf 100644 --- a/include/express/scope.h +++ b/include/express/scope.h @@ -134,14 +134,16 @@ struct Scope_ { /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT struct Symbol_ * SCOPE_get_symbol PROTO( ( Generic ) ); -extern SC_EXPRESS_EXPORT void SCOPE_get_entities PROTO( ( Scope, Linked_List ) ); -extern SC_EXPRESS_EXPORT Linked_List SCOPEget_entities PROTO( ( Scope ) ); -extern SC_EXPRESS_EXPORT Linked_List SCOPEget_entities_superclass_order PROTO( ( Scope ) ); -extern SC_EXPRESS_EXPORT Generic SCOPEfind PROTO( ( Scope, char *, int ) ); -extern SC_EXPRESS_EXPORT void SCOPE_get_functions PROTO( ( Scope, Linked_List ) ); -extern SC_EXPRESS_EXPORT Linked_List SCOPEget_functions PROTO( ( Scope ) ); -extern SC_EXPRESS_EXPORT void SCOPE_get_rules PROTO( ( Scope, Linked_List ) ); -extern SC_EXPRESS_EXPORT Linked_List SCOPEget_rules PROTO( ( Scope ) ); +extern SC_EXPRESS_EXPORT struct Symbol_ * SCOPE_get_symbol( void * ); +extern SC_EXPRESS_EXPORT void SCOPE_get_entities( Scope, Linked_List ); +extern SC_EXPRESS_EXPORT Linked_List SCOPEget_entities( Scope ); +extern SC_EXPRESS_EXPORT Linked_List SCOPEget_entities_superclass_order( Scope ); +extern SC_EXPRESS_EXPORT void * SCOPEfind( Scope, char *, int ); +extern SC_EXPRESS_EXPORT void SCOPE_get_functions( Scope, Linked_List ); +extern SC_EXPRESS_EXPORT Linked_List SCOPEget_functions( Scope ); +extern SC_EXPRESS_EXPORT void SCOPE_get_rules( Scope, Linked_List ); +extern SC_EXPRESS_EXPORT Linked_List SCOPEget_rules( Scope ); + +void * SCOPE_find( Scope, char *, int ); #endif /* SCOPE_H */ diff --git a/include/express/stmt.h b/include/express/stmt.h index 2a2acd10e..21f5e4645 100644 --- a/include/express/stmt.h +++ b/include/express/stmt.h @@ -27,7 +27,7 @@ * CADDETC certified * * Revision 1.5 1993/02/16 03:27:02 libes - * removed artifical begin/end nesting for improved reconstruction (printing) + * removed artificial begin/end nesting for improved reconstruction (printing) * of original Express file * * Revision 1.4 1992/08/18 17:12:41 libes @@ -183,28 +183,28 @@ extern SC_EXPRESS_EXPORT Statement STATEMENT_SKIP; /* macro function definitions */ /******************************/ -#define STMT_new() (struct Statement_ *)MEM_new(&STMT_fl) -#define STMT_destroy(x) MEM_destroy(&STMT_fl,(Freelist *)(Generic)x) - -#define ALIAS_new() (struct Alias_ *)MEM_new(&ALIAS_fl) -#define ALIAS_destroy(x) MEM_destroy(&ALIAS_fl,(Freelist *)(Generic)x) -#define ASSIGN_new() (struct Assignment_ *)MEM_new(&ASSIGN_fl) -#define ASSIGN_destroy(x) MEM_destroy(&ASSIGN_fl,(Freelist *)(Generic)x) -#define CASE_new() (struct Case_Statement_ *)MEM_new(&CASE_fl) -#define CASE_destroy(x) MEM_destroy(&CASE_fl,(Freelist *)(Generic)x) -#define COMP_STMT_new() (struct Compound_Statement_ *)MEM_new(&COMP_STMT_fl) -#define COMP_STMT_destroy(x) MEM_destroy(&COMP_STMT_fl,(Freelist *)(Generic)x) -#define COND_new() (struct Conditional_ *)MEM_new(&COND_fl) -#define COND_destroy(x) MEM_destroy(&COND_fl,(Freelist *)(Generic)x) -#define LOOP_new() (struct Loop_ *)MEM_new(&LOOP_fl) -#define LOOP_destroy(x) MEM_destroy(&LOOP_fl,(Freelist *)(Generic)x) -#define PCALL_new() (struct Procedure_Call_ *)MEM_new(&PCALL_fl) -#define PCALL_destroy(x) MEM_destroy(&PCALL_fl,(Freelist *)(Generic)x) -#define RET_new() (struct Return_Statement_ *)MEM_new(&RET_fl) -#define RET_destroy(x) MEM_destroy(&RET_fl,(Freelist *)(Generic)x) - -#define INCR_new() (struct Increment_ *)MEM_new(&INCR_fl) -#define INCR_destroy(x) MEM_destroy(&INCR_fl,(Freelist *)(char *)x) +#define STMT_new() (struct Statement_ *)ALLOC_new(&STMT_fl) +#define STMT_destroy(x) ALLOC_destroy(&STMT_fl,(Freelist *)x) + +#define ALIAS_new() (struct Alias_ *)ALLOC_new(&ALIAS_fl) +#define ALIAS_destroy(x) ALLOC_destroy(&ALIAS_fl,(Freelist *)x) +#define ASSIGN_new() (struct Assignment_ *)ALLOC_new(&ASSIGN_fl) +#define ASSIGN_destroy(x) ALLOC_destroy(&ASSIGN_fl,(Freelist *)x) +#define CASE_new() (struct Case_Statement_ *)ALLOC_new(&CASE_fl) +#define CASE_destroy(x) ALLOC_destroy(&CASE_fl,(Freelist *)x) +#define COMP_STMT_new() (struct Compound_Statement_ *)ALLOC_new(&COMP_STMT_fl) +#define COMP_STMT_destroy(x) ALLOC_destroy(&COMP_STMT_fl,(Freelist *)x) +#define COND_new() (struct Conditional_ *)ALLOC_new(&COND_fl) +#define COND_destroy(x) ALLOC_destroy(&COND_fl,(Freelist *)x) +#define LOOP_new() (struct Loop_ *)ALLOC_new(&LOOP_fl) +#define LOOP_destroy(x) ALLOC_destroy(&LOOP_fl,(Freelist *)x) +#define PCALL_new() (struct Procedure_Call_ *)ALLOC_new(&PCALL_fl) +#define PCALL_destroy(x) ALLOC_destroy(&PCALL_fl,(Freelist *)x) +#define RET_new() (struct Return_Statement_ *)ALLOC_new(&RET_fl) +#define RET_destroy(x) ALLOC_destroy(&RET_fl,(Freelist *)x) + +#define INCR_new() (struct Increment_ *)ALLOC_new(&INCR_fl) +#define INCR_destroy(x) ALLOC_destroy(&INCR_fl,(Freelist *)(char *)x) #define ASSIGNget_lhs(s) ((s)->u.assign->lhs) #define ASSIGNget_rhs(s) ((s)->u.assign->rhs) @@ -225,17 +225,17 @@ extern SC_EXPRESS_EXPORT Statement STATEMENT_SKIP; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT Statement STMTcreate PROTO( ( int ) ); -extern SC_EXPRESS_EXPORT Statement ALIAScreate PROTO( ( struct Scope_ *, Variable, Linked_List ) ); -extern SC_EXPRESS_EXPORT Statement CASEcreate PROTO( ( Expression , Linked_List ) ); -extern SC_EXPRESS_EXPORT Statement ASSIGNcreate PROTO( ( Expression , Expression ) ); -extern SC_EXPRESS_EXPORT Statement COMP_STMTcreate PROTO( ( Linked_List ) ); -extern SC_EXPRESS_EXPORT Statement CONDcreate PROTO( ( Expression, Linked_List, Linked_List ) ); -extern SC_EXPRESS_EXPORT Statement LOOPcreate PROTO( ( struct Scope_ *, Expression, Expression, Linked_List ) ); -extern SC_EXPRESS_EXPORT Statement PCALLcreate PROTO( ( Linked_List ) ); -extern SC_EXPRESS_EXPORT Statement RETcreate PROTO( ( Expression ) ); -extern SC_EXPRESS_EXPORT void STMTinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT struct Scope_ * INCR_CTLcreate PROTO( ( Symbol *, Expression start, - Expression end, Expression increment ) ); +extern SC_EXPRESS_EXPORT Statement STMTcreate( int ); +extern SC_EXPRESS_EXPORT Statement ALIAScreate( struct Scope_ *, Variable, Linked_List ); +extern SC_EXPRESS_EXPORT Statement CASEcreate( Expression , Linked_List ); +extern SC_EXPRESS_EXPORT Statement ASSIGNcreate( Expression , Expression ); +extern SC_EXPRESS_EXPORT Statement COMP_STMTcreate( Linked_List ); +extern SC_EXPRESS_EXPORT Statement CONDcreate( Expression, Linked_List, Linked_List ); +extern SC_EXPRESS_EXPORT Statement LOOPcreate( struct Scope_ *, Expression, Expression, Linked_List ); +extern SC_EXPRESS_EXPORT Statement PCALLcreate( Linked_List ); +extern SC_EXPRESS_EXPORT Statement RETcreate( Expression ); +extern SC_EXPRESS_EXPORT void STMTinitialize( void ); +extern SC_EXPRESS_EXPORT struct Scope_ * INCR_CTLcreate( Symbol *, Expression start, + Expression end, Expression increment ); #endif /*STATEMENT_H*/ diff --git a/include/express/symbol.h b/include/express/symbol.h index 5e2acc4a4..b589b01e2 100644 --- a/include/express/symbol.h +++ b/include/express/symbol.h @@ -45,7 +45,7 @@ #include #include "basic.h" /* get basic definitions */ -#include "memory.h" +#include "alloc.h" /************/ /* typedefs */ @@ -78,8 +78,8 @@ extern SC_EXPRESS_EXPORT struct freelist_head SYMBOL_fl; /* macro function definitions */ /******************************/ -#define SYMBOL_new() (struct Symbol_ *)MEM_new(&SYMBOL_fl) -#define SYMBOL_destroy(x) MEM_destroy(&SYMBOL_fl,(Freelist *)(Generic)x) +#define SYMBOL_new() (struct Symbol_ *)ALLOC_new(&SYMBOL_fl) +#define SYMBOL_destroy(x) ALLOC_destroy(&SYMBOL_fl,(Freelist *)x) #define SYMBOLset(obj) obj->symbol.line = yylineno; \ obj->symbol.filename = current_filename @@ -88,7 +88,7 @@ extern SC_EXPRESS_EXPORT struct freelist_head SYMBOL_fl; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT void SYMBOLinitialize PROTO( ( void ) ); +extern SC_EXPRESS_EXPORT void SYMBOLinitialize( void ); SC_EXPRESS_EXPORT Symbol * SYMBOLcreate( char * name, int line, const char * filename ); #endif /* SYMBOL_H */ diff --git a/include/express/type.h b/include/express/type.h index 3cd5ff1a6..321fe716e 100644 --- a/include/express/type.h +++ b/include/express/type.h @@ -217,16 +217,14 @@ extern SC_EXPRESS_EXPORT Type Type_Bag_Of_Generic; extern SC_EXPRESS_EXPORT struct freelist_head TYPEHEAD_fl; extern SC_EXPRESS_EXPORT struct freelist_head TYPEBODY_fl; -extern SC_EXPRESS_EXPORT Error ERROR_corrupted_type; - /******************************/ /* macro function definitions */ /******************************/ -#define TYPEHEAD_new() (struct TypeHead_ *)MEM_new(&TYPEHEAD_fl) -#define TYPEHEAD_destroy(x) MEM_destroy(&TYPEHEAD_fl,(Freelist *)(Generic)x) -#define TYPEBODY_new() (struct TypeBody_ *)MEM_new(&TYPEBODY_fl) -#define TYPEBODY_destroy(x) MEM_destroy(&TYPEBODY_fl,(Freelist *)(Generic)x) +#define TYPEHEAD_new() (struct TypeHead_ *)ALLOC_new(&TYPEHEAD_fl) +#define TYPEHEAD_destroy(x) ALLOC_destroy(&TYPEHEAD_fl,(Freelist *)x) +#define TYPEBODY_new() (struct TypeBody_ *)ALLOC_new(&TYPEBODY_fl) +#define TYPEBODY_destroy(x) ALLOC_destroy(&TYPEBODY_fl,(Freelist *)x) #define TYPEis(t) ((t)->u.type->body->type) #define TYPEis_identifier(t) ((t)->u.type->body->type == identifier_) @@ -293,20 +291,20 @@ extern SC_EXPRESS_EXPORT Error ERROR_corrupted_type; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT Type TYPEcreate_partial PROTO( ( struct Symbol_ *, Scope ) ); +extern SC_EXPRESS_EXPORT Type TYPEcreate_partial( struct Symbol_ *, Scope ); -extern SC_EXPRESS_EXPORT Type TYPEcreate PROTO( ( enum type_enum ) ); -extern SC_EXPRESS_EXPORT Type TYPEcreate_from_body_anonymously PROTO( ( TypeBody ) ); -extern SC_EXPRESS_EXPORT Type TYPEcreate_name PROTO( ( struct Symbol_ * ) ); -extern SC_EXPRESS_EXPORT Type TYPEcreate_nostab PROTO( ( struct Symbol_ *, Scope, char ) ); -extern SC_EXPRESS_EXPORT TypeBody TYPEBODYcreate PROTO( ( enum type_enum ) ); -extern SC_EXPRESS_EXPORT void TYPEinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT void TYPEcleanup PROTO( ( void ) ); +extern SC_EXPRESS_EXPORT Type TYPEcreate( enum type_enum ); +extern SC_EXPRESS_EXPORT Type TYPEcreate_from_body_anonymously( TypeBody ); +extern SC_EXPRESS_EXPORT Type TYPEcreate_name( struct Symbol_ * ); +extern SC_EXPRESS_EXPORT Type TYPEcreate_nostab( struct Symbol_ *, Scope, char ); +extern SC_EXPRESS_EXPORT TypeBody TYPEBODYcreate( enum type_enum ); +extern SC_EXPRESS_EXPORT void TYPEinitialize( void ); +extern SC_EXPRESS_EXPORT void TYPEcleanup( void ); -extern SC_EXPRESS_EXPORT bool TYPEinherits_from PROTO( ( Type, enum type_enum ) ); -extern SC_EXPRESS_EXPORT Type TYPEget_nonaggregate_base_type PROTO( ( Type ) ); +extern SC_EXPRESS_EXPORT bool TYPEinherits_from( Type, enum type_enum ); +extern SC_EXPRESS_EXPORT Type TYPEget_nonaggregate_base_type( Type ); -extern SC_EXPRESS_EXPORT Type TYPEcreate_user_defined_type PROTO( ( Type, Scope, struct Symbol_ * ) ); -extern SC_EXPRESS_EXPORT Type TYPEcreate_user_defined_tag PROTO( ( Type, Scope, struct Symbol_ * ) ); +extern SC_EXPRESS_EXPORT Type TYPEcreate_user_defined_type( Type, Scope, struct Symbol_ * ); +extern SC_EXPRESS_EXPORT Type TYPEcreate_user_defined_tag( Type, Scope, struct Symbol_ * ); #endif /* TYPE_H */ diff --git a/include/express/variable.h b/include/express/variable.h index 0b6a781e7..308116459 100644 --- a/include/express/variable.h +++ b/include/express/variable.h @@ -105,8 +105,8 @@ extern SC_EXPRESS_EXPORT struct freelist_head VAR_fl; /* macro function definitions */ /******************************/ -#define VAR_new() (struct Variable_ *)MEM_new(&VAR_fl) -#define VAR_destroy(x) MEM_destroy(&VAR_fl,(Freelist *)(Generic)x) +#define VAR_new() (struct Variable_ *)ALLOC_new(&VAR_fl) +#define VAR_destroy(x) ALLOC_destroy(&VAR_fl,(Freelist *)x) #define VARget_name(v) ((v)->name) #define VARput_name(v,n) ((v)->name = (n)) @@ -125,8 +125,8 @@ extern SC_EXPRESS_EXPORT struct freelist_head VAR_fl; /* function prototypes */ /***********************/ -extern SC_EXPRESS_EXPORT Variable VARcreate PROTO( ( Expression, Type ) ); -extern SC_EXPRESS_EXPORT void VARinitialize PROTO( ( void ) ); -extern SC_EXPRESS_EXPORT char * VARget_simple_name PROTO( ( Variable ) ); +extern SC_EXPRESS_EXPORT Variable VARcreate( Expression, Type ); +extern SC_EXPRESS_EXPORT void VARinitialize( void ); +extern SC_EXPRESS_EXPORT char * VARget_simple_name( Variable ); #endif /* VARIABLE_H */ diff --git a/include/sc_export.h b/include/sc_export.h index e128c4906..2f51c9ff5 100644 --- a/include/sc_export.h +++ b/include/sc_export.h @@ -2,107 +2,91 @@ #define SC_EXPORT_H /* Import/Export flags for base. */ -#ifndef SC_BASE_EXPORT -# if defined(SC_BASE_DLL_EXPORTS) && defined(SC_BASE_DLL_IMPORTS) -# error "Only SC_BASE_DLL_EXPORTS or SC_BASE_DLL_IMPORTS can be defined, not both." -# elif defined(SC_BASE_DLL_EXPORTS) +#if !defined(SC_STATIC) && defined(_WIN32) +# if defined(SC_BASE_DLL_EXPORTS) # define SC_BASE_EXPORT __declspec(dllexport) -# elif defined(SC_BASE_DLL_IMPORTS) -# define SC_BASE_EXPORT __declspec(dllimport) # else -# define SC_BASE_EXPORT +# define SC_BASE_EXPORT __declspec(dllimport) # endif +#else +# define SC_BASE_EXPORT #endif /* Import/Export flags for express. */ -#ifndef SC_EXPRESS_EXPORT -# if defined(SC_EXPRESS_DLL_EXPORTS) && defined(SC_EXPRESS_DLL_IMPORTS) -# error "Only SC_EXPRESS_DLL_EXPORTS or SC_EXPRESS_DLL_IMPORTS can be defined, not both." -# elif defined(SC_EXPRESS_DLL_EXPORTS) -# define SC_EXPRESS_EXPORT __declspec(dllexport) -# elif defined(SC_EXPRESS_DLL_IMPORTS) -# define SC_EXPRESS_EXPORT __declspec(dllimport) -# else -# define SC_EXPRESS_EXPORT -# endif +#if !defined(SC_STATIC) && defined(_WIN32) +# if defined(SC_EXPRESS_DLL_EXPORTS) +# define SC_EXPRESS_EXPORT __declspec(dllexport) +# else +# define SC_EXPRESS_EXPORT __declspec(dllimport) +# endif +#else +# define SC_EXPRESS_EXPORT #endif /* Import/Export flags for exppp. */ -#ifndef SC_EXPPP_EXPORT -# if defined(SC_EXPPP_DLL_EXPORTS) && defined(SC_EXPPP_DLL_IMPORTS) -# error "Only SC_EXPPP_DLL_EXPORTS or SC_EXPPP_DLL_IMPORTS can be defined, not both." -# elif defined(SC_EXPPP_DLL_EXPORTS) -# define SC_EXPPP_EXPORT __declspec(dllexport) -# elif defined(SC_EXPPP_DLL_IMPORTS) -# define SC_EXPPP_EXPORT __declspec(dllimport) -# else -# define SC_EXPPP_EXPORT -# endif +#if !defined(SC_STATIC) && defined(_WIN32) +# if defined(SC_EXPPP_DLL_EXPORTS) +# define SC_EXPPP_EXPORT __declspec(dllexport) +# else +# define SC_EXPPP_EXPORT __declspec(dllimport) +# endif +#else +# define SC_EXPPP_EXPORT #endif /* Import/Export flags for utils. */ -#ifndef SC_UTILS_EXPORT -# if defined(SC_UTILS_DLL_EXPORTS) && defined(SC_UTILS_DLL_IMPORTS) -# error "Only SC_UTILS_DLL_EXPORTS or SC_UTILS_DLL_IMPORTS can be defined, not both." -# elif defined(SC_UTILS_DLL_EXPORTS) -# define SC_UTILS_EXPORT __declspec(dllexport) -# elif defined(SC_UTILS_DLL_IMPORTS) -# define SC_UTILS_EXPORT __declspec(dllimport) -# else -# define SC_UTILS_EXPORT -# endif +#if !defined(SC_STATIC) && defined(_WIN32) +# if defined(SC_UTILS_DLL_EXPORTS) +# define SC_UTILS_EXPORT __declspec(dllexport) +# else +# define SC_UTILS_EXPORT __declspec(dllimport) +# endif +#else +# define SC_UTILS_EXPORT #endif /* Import/Export flags for dai. */ -#ifndef SC_DAI_EXPORT -# if defined(SC_DAI_DLL_EXPORTS) && defined(SC_DAI_DLL_IMPORTS) -# error "Only SC_DAI_DLL_EXPORTS or SC_DAI_DLL_IMPORTS can be defined, not both." -# elif defined(SC_DAI_DLL_EXPORTS) -# define SC_DAI_EXPORT __declspec(dllexport) -# elif defined(SC_DAI_DLL_IMPORTS) -# define SC_DAI_EXPORT __declspec(dllimport) -# else -# define SC_DAI_EXPORT -# endif +#if !defined(SC_STATIC) && defined(_WIN32) +# if defined(SC_DAI_DLL_EXPORTS) +# define SC_DAI_EXPORT __declspec(dllexport) +# else +# define SC_DAI_EXPORT __declspec(dllimport) +# endif +#else +# define SC_DAI_EXPORT #endif /* Import/Export flags for core. */ -#ifndef SC_CORE_EXPORT -# if defined(SC_CORE_DLL_EXPORTS) && defined(SC_CORE_DLL_IMPORTS) -# error "Only SC_CORE_DLL_EXPORTS or SC_CORE_DLL_IMPORTS can be defined, not both." -# elif defined(SC_CORE_DLL_EXPORTS) -# define SC_CORE_EXPORT __declspec(dllexport) -# elif defined(SC_CORE_DLL_IMPORTS) -# define SC_CORE_EXPORT __declspec(dllimport) -# else -# define SC_CORE_EXPORT -# endif +#if !defined(SC_STATIC) && defined(_WIN32) +# if defined(SC_CORE_DLL_EXPORTS) +# define SC_CORE_EXPORT __declspec(dllexport) +# else +# define SC_CORE_EXPORT __declspec(dllimport) +# endif +#else +# define SC_CORE_EXPORT #endif /* Import/Export flags for editor. */ -#ifndef SC_EDITOR_EXPORT -# if defined(SC_EDITOR_DLL_EXPORTS) && defined(SC_EDITOR_DLL_IMPORTS) -# error "Only SC_EDITOR_DLL_EXPORTS or SC_EDITOR_DLL_IMPORTS can be defined, not both." -# elif defined(SC_EDITOR_DLL_EXPORTS) -# define SC_EDITOR_EXPORT __declspec(dllexport) -# elif defined(SC_EDITOR_DLL_IMPORTS) -# define SC_EDITOR_EXPORT __declspec(dllimport) -# else -# define SC_EDITOR_EXPORT -# endif +#if !defined(SC_STATIC) && defined(_WIN32) +# if defined(SC_EDITOR_DLL_EXPORTS) +# define SC_EDITOR_EXPORT __declspec(dllexport) +# else +# define SC_EDITOR_EXPORT __declspec(dllimport) +# endif +#else +# define SC_EDITOR_EXPORT #endif /* Import/Export flags for lazyfile. */ -#ifndef SC_LAZYFILE_EXPORT -# if defined(SC_LAZYFILE_DLL_EXPORTS) && defined(SC_LAZYFILE_DLL_IMPORTS) -# error "Only SC_LAZYFILE_DLL_EXPORTS or SC_LAZYFILE_DLL_IMPORTS can be defined, not both." -# elif defined(SC_LAZYFILE_DLL_EXPORTS) -# define SC_LAZYFILE_EXPORT __declspec(dllexport) -# elif defined(SC_LAZYFILE_DLL_IMPORTS) -# define SC_LAZYFILE_EXPORT __declspec(dllimport) -# else -# define SC_LAZYFILE_EXPORT -# endif +#if !defined(SC_STATIC) && defined(_WIN32) +# if defined(SC_LAZYFILE_DLL_EXPORTS) +# define SC_LAZYFILE_EXPORT __declspec(dllexport) +# else +# define SC_LAZYFILE_EXPORT __declspec(dllimport) +# endif +#else +# define SC_LAZYFILE_EXPORT #endif #endif /* SC_EXPORT_H */ diff --git a/include/sc_stdbool.h b/include/sc_stdbool.h deleted file mode 100644 index 5d126dffc..000000000 --- a/include/sc_stdbool.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef STDBOOL_H_ -#define STDBOOL_H_ - -/** - * stdbool.h - ISO C99 Boolean type - * Author - Bill Chatfield - * E-mail - bill underscore chatfield at yahoo dot com - * Copyright - You are free to use for any purpose except illegal acts - * Warrenty - None: don't blame me if it breaks something - * - * In ISO C99, stdbool.h is a standard header and _Bool is a keyword, but - * some compilers don't offer these yet. This header file is an - * implementation of the standard ISO C99 stdbool.h header file. It checks - * for various compiler versions and defines things that are missing in - * those versions. - * - * The GNU and Watcom compilers include a stdbool.h, but the Borland - * C/C++ 5.5.1 compiler and the Microsoft compilers do not. - * - * See http://predef.sourceforge.net/precomp.html for compile macros. - */ - -#ifndef __cplusplus - -/** - * Borland C++ 5.5.1 does not define _Bool. - */ -#if defined(__BORLANDC__) && __BORLANDC__ < 0x630 -typedef int _Bool; -#endif - -/** - * Microsoft C/C++ version 14.00.50727.762, which comes with Visual C++ 2005, - * and version 15.00.30729.01, which comes with Visual C++ 2008, do not - * define _Bool. - */ -#if defined(_MSC_VER) && _MSC_VER<1800 -typedef int _Bool; -#endif - -/** - * Define the Boolean macros only if they are not already defined. - */ -#ifndef __bool_true_false_are_defined -#define bool _Bool -#define false 0 -#define true 1 -#define __bool_true_false_are_defined 1 -#endif - -#endif /* __cplusplus */ - -#endif /*STDBOOL_H_*/ diff --git a/misc/flawfinder b/misc/flawfinder index 680e65dc5..151a48fb8 100755 --- a/misc/flawfinder +++ b/misc/flawfinder @@ -102,7 +102,7 @@ blank_line = re.compile( r'(?m)^\s+$' ) # --- OLDFILENAME OLDTIMESTAMP # +++ NEWFILENAME NEWTIMESTAMP # @@ -OLDSTART,OLDLENGTH +NEWSTART,NEWLENGTH @@ -# ... Changes where preceeding "+" is add, "-" is remove, " " is unchanged. +# ... Changes where preceding "+" is add, "-" is remove, " " is unchanged. # # ",OLDLENGTH" and ",NEWLENGTH" are optional (they default to 1). # GNU unified diff format doesn't normally output "Index:"; you use @@ -451,7 +451,7 @@ def extract_c_parameters(text, pos=0): # so will get confused by patterns like gettext("hi") + function("bye") # In practice, this doesn't seem to be a problem; gettext() is usually # wrapped around the entire parameter. -# The ?s makes it posible to match multi-line strings. +# The ?s makes it possible to match multi-line strings. gettext_pattern = re.compile(r'(?s)^\s*' + 'gettext' + r'\s*\((.*)\)\s*$') undersc_pattern = re.compile(r'(?s)^\s*' + '_(T(EXT)?)?' + r'\s*\((.*)\)\s*$') @@ -703,7 +703,7 @@ c_ruleset = { "lstrcpyn|wcsncpy|_tcsncpy|_mbsnbcpy" : (c_buffer, 1, # Low risk level, because this is often used correctly when FIXING security - # problems, and raising it to a higher risk levle would cause many false positives. + # problems, and raising it to a higher risk level would cause many false positives. "Easily used incorrectly; doesn't always \\0-terminate or " + "check for invalid pointers", "", diff --git a/misc/header_mv.sh b/misc/header_mv.sh new file mode 100755 index 000000000..0d2be0f0f --- /dev/null +++ b/misc/header_mv.sh @@ -0,0 +1,10 @@ +#!/bin/bash +find . -type f -path "*/cl*" -not -path "*.git/*" -not -path "*/exp*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include \"$1\"/include \"utils\/$1\"/g" {} \; +find . -type f -path "*/cl*" -not -path "*.git/*" -not -path "*/exp*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include <$1>/include \"utils\/$1\"/g" {} \; + +find . -type f -path "*/include*" -not -path "*.git/*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include \"$1\"/include \"utils\/$1\"/g" {} \; +find . -type f -path "*/include*" -not -path "*.git/*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include <$1>/include \"utils\/$1\"/g" {} \; + +find . -type f -path "*/test*" -not -path "*.git/*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include \"$1\"/include \"utils\/$1\"/g" {} \; +find . -type f -path "*/test*" -not -path "*.git/*" -regex '.*\(c\|cc\|cpp\|cxx\|h\|hpp\)$' -exec perl -0777 -pi -e "s/include <$1>/include \"utils\/$1\"/g" {} \; + diff --git a/misc/summarize-appveyor-log.go b/misc/summarize-appveyor-log.go deleted file mode 100644 index f14d888ce..000000000 --- a/misc/summarize-appveyor-log.go +++ /dev/null @@ -1,330 +0,0 @@ -//summarize MSVC errors from an appveyor log -// compile with 'go build summarize-appveyor-log.go' -// takes 0 or 1 args; with 0, gets log from latest -// build. with 1, uses that file as raw json-like log -package main - -import ( - "bufio" - "encoding/json" - "fmt" - "io" - "net/http" - "os" - "regexp" - "sort" - "strings" -) - -const ( - headerKey = "Authorization" - headerVal = "Bearer %s" - projUrl = "https://ci.appveyor.com/api/projects/mpictor/stepcode" - //"https://ci.appveyor.com/api/buildjobs/2rjxdv1rnb8jcg8y/log" - logUrl = "https://ci.appveyor.com/api/buildjobs/%s/log" - consoleUrl = "https://ci.appveyor.com/api/buildjobs/%s/console" -) - -func main() { - var rawlog io.ReadCloser - var build string - var err error - if len(os.Args) == 2 { - rawlog, build, err = processArgv() - } else { - rawlog, build, err = getLog() - } - if err != nil { - fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) - return - } - defer rawlog.Close() - log := decodeConsole(rawlog) - warns, errs := countMessages(log) - fi, err := os.Create(fmt.Sprintf("appveyor-%s.smy", build)) - if err != nil { - fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) - return - } - printMessages("error", errs, fi) - printMessages("warning", warns, fi) - - fmt.Printf("done\n") - -} - -/* categorizes warnings and errors based upon the MSVC message number (i.e. C4244) - * the regex will match lines like -c:\projects\stepcode\src\base\sc_benchmark.h(45): warning C4251: 'benchmark::descr' : class 'std::basic_string,std::allocator>' needs to have dll-interface to be used by clients of class 'benchmark' [C:\projects\STEPcode\build\src\base\base.vcxproj] -[00:03:48] C:\projects\STEPcode\src\base\sc_benchmark.cc(61): warning C4244: '=' : conversion from 'SIZE_T' to 'long', possible loss of data [C:\projects\STEPcode\build\src\base\base.vcxproj]* -*/ -func countMessages(log []string) (warns, errs map[string][]string) { - warns = make(map[string][]string) - errs = make(map[string][]string) - fname := " *(.*)" // $1 - fline := `(?:\((\d+)\)| ): ` // $2 - either line number in parenthesis or a space, followed by a colon - msgNr := `([A-Z]+\d+): ` // $3 - C4251, LNK2005, etc - msgTxt := `([^\[]*) ` // $4 - tail := `\[[^\[\]]*\]` - warnRe := regexp.MustCompile(fname + fline + `warning ` + msgNr + msgTxt + tail) - errRe := regexp.MustCompile(fname + fline + `(?:fatal )?error ` + msgNr + msgTxt + tail) - for _, line := range log { - if warnRe.MatchString(line) { - key := warnRe.ReplaceAllString(line, "$3") - path := strings.ToLower(warnRe.ReplaceAllString(line, "$1:$2")) - arr := warns[key] - if arr == nil { - arr = make([]string, 5) - //detailed text as first string in array - text := warnRe.ReplaceAllString(line, "$4") - arr[0] = fmt.Sprintf("%s", text) - } - //eliminate duplicates - match := false - for _, l := range arr { - if l == path { - match = true - } - } - if !match { - warns[key] = append(arr, path) - } - } else if errRe.MatchString(line) { - key := errRe.ReplaceAllString(line, "$3") - path := strings.ToLower(errRe.ReplaceAllString(line, "$1:$2")) - arr := errs[key] - if arr == nil { - arr = make([]string, 5) - //detailed text as first string in array - text := errRe.ReplaceAllString(line, "$4") - arr[0] = fmt.Sprintf("%s", text) - } - //eliminate duplicates - match := false - for _, l := range arr { - if l == path { - match = true - } - } - if !match { - errs[key] = append(arr, path) - } - } - } - return -} - -func printMessages(typ string, m map[string][]string, w io.Writer) { - //sort keys - keys := make([]string, 0, len(m)) - for key := range m { - keys = append(keys, key) - } - sort.Strings(keys) - for _, k := range keys { - for i, l := range m[k] { - //first string is an example, not a location - if i == 0 { - fmt.Fprintf(w, "%s %s (i.e. \"%s\")\n", typ, k, l) - } else if len(l) > 1 { //not sure where blank lines are coming from... - fmt.Fprintf(w, " >> %s\n", l) - } - } - } -} - -//structs from http://json2struct.mervine.net/ - -//{"values":[{"i":0,"t":"Specify a project or solution file. The directory does not contain a project or solution file.\r\n","dt":"00:00:04","bg":12,"fg":15}]} -type AppVeyorConsoleLines struct { - Values []struct { - I int `json:"i"` - Text string `json:"t"` - DateTime string `json:"dt"` - BgColor int `json:"bg"` - FgColor int `json:"fg"` - } -} -type AppVeyorBuild struct { - Build struct { - /*BuildNumber int `json:"buildNumber"`*/ - Version string `json:"version"` - Jobs []struct { - JobID string `json:"jobId"` - } `json:"jobs"` - } `json:"build"` -} - -func splitAppend(log *[]string, blob string) { - //blob = strings.Replace(blob,"\r\n", "\n",-1) - blob = strings.Replace(blob, "\\", "/", -1) - r := strings.NewReader(blob) - unwrapScanner := bufio.NewScanner(r) - for unwrapScanner.Scan() { - txt := unwrapScanner.Text() - //fmt.Printf("%s\n", txt) - *log = append(*log, txt) - } -} - -//calculate length of string without escape chars -// func escapeLen(s string)(l int) { -// //s = strings.Replace(s,"\\\\", "/",-1) -// s = strings.Replace(s,"\\\"", "",-1) -// s = strings.Replace(s,"\r\n", "RN",-1) -// return len(s) -// } - - -//decode the almost-JSON console data from appveyor -func decodeConsole(r io.Reader) (log []string) { - wrapper := Wrap(r) - dec := json.NewDecoder(wrapper) - var consoleLines AppVeyorConsoleLines - var err error - var txtBlob string - err = dec.Decode(&consoleLines) - if err == io.EOF { - err = nil - } - if err == nil { - for _, l := range consoleLines.Values { - txtBlob += l.Text - //el := escapeLen(l.Text) - //something inserts newlines at 229 chars (+\n\r == 231) (found in CMake output) - lenTwoThreeOne := len(l.Text) == 231 - if lenTwoThreeOne { - txtBlob = strings.TrimSuffix(txtBlob, "\r\n") - } - //something else starts new log lines at 1024 chars without inserting newlines (found in CTest error output) - if len(l.Text) != 1024 && !lenTwoThreeOne { - //fmt.Printf("sa for l %d, el %d\n", len(l.Text),el) - splitAppend(&log, txtBlob) - txtBlob = "" - } - } - } else { - fmt.Printf("decode err %s\n", err) - } - if len(txtBlob) > 0 { - splitAppend(&log, txtBlob) - } - return -} - -func processArgv() (log io.ReadCloser, build string, err error) { - fname := os.Args[1] - if len(fname) < 14 { - err = fmt.Errorf("Name arg '%s' too short. Run as '%s appveyor-NNN.log'", fname, os.Args[0]) - return - } - buildRe := regexp.MustCompile(`appveyor-(.+).log`) - build = buildRe.ReplaceAllString(fname, "$1") - if len(build) == 0 { - err = fmt.Errorf("No build id in %s", fname) - return - } - log, err = os.Open(fname) - return -} - -func getLog() (log io.ReadCloser, build string, err error) { - client := &http.Client{} - req, err := http.NewRequest("GET", projUrl, nil) - if err != nil { - return - } - apikey := os.Getenv("APPVEYOR_API_KEY") - //api key isn't necessary for read-only queries on public projects - if len(apikey) > 0 { - req.Header.Add(headerKey, fmt.Sprintf(headerVal, apikey)) - } //else { - // fmt.Printf("Env var APPVEYOR_API_KEY is not set.") - //} - resp, err := client.Do(req) - if err != nil { - return - } - - build, job := decodeProjInfo(resp.Body) - fmt.Printf("build #%s, jobId %s\n", build, job) - resp, err = http.Get(fmt.Sprintf(consoleUrl, job)) - if err != nil { - return - } - logName := fmt.Sprintf("appveyor-%s.log", build) - fi, err := os.Create(logName) - if err != nil { - return - } - _, err = io.Copy(fi, resp.Body) - if err != nil { - return - } - log, err = os.Open(logName) - if err != nil { - log = nil - } - return -} - -func decodeProjInfo(r io.Reader) (vers string, job string) { - dec := json.NewDecoder(r) - var av AppVeyorBuild - err := dec.Decode(&av) - if err != io.EOF && err != nil { - fmt.Printf("err %s\n", err) - return - } - if len(av.Build.Jobs) != 1 { - return - } - vers = av.Build.Version - job = av.Build.Jobs[0].JobID - return -} - -//wrap a reader, modifying content to make the json decoder happy -//only tested with data from appveyor console -type jsonWrapper struct { - source io.Reader - begin bool - end bool -} - -func Wrap(r io.Reader) *jsonWrapper { - return &jsonWrapper{ - source: r, - begin: true, - } -} - -// func nonNeg(n int) (int) { -// if n < 0 { -// return 0 -// } -// return n -// } - -func (w *jsonWrapper) Read(p []byte) (n int, err error) { - if w.end { - return 0, io.EOF - } - if w.begin { - w.begin = false - n = copy(p, []byte(`{"values":[`)) - } - m, err := w.source.Read(p[n:]) - n += m - if err == io.EOF { - w.end = true - if n < len(p) { - n = copy(p, []byte(`{"dummy":"data"}]}`)) - } else { - err = fmt.Errorf("No room to terminate JSON struct with '}'\n") - } - } - return -} - -// kate: indent-width 8; space-indent off; replace-tabs off; replace-tabs-save off; replace-trailing-space-save on; remove-trailing-space on; tab-intent on; tab-width 8; show-tabs off; diff --git a/misc/wiki-scripts/update-matrix.py b/misc/wiki-scripts/update-matrix.py index 9893cf38e..65894726e 100644 --- a/misc/wiki-scripts/update-matrix.py +++ b/misc/wiki-scripts/update-matrix.py @@ -5,6 +5,7 @@ #must be ran from scl/build_matrix +from __future__ import print_function from xml.etree import ElementTree as ET import os from datetime import date @@ -49,7 +50,7 @@ def find_xml(): if str(date.today().year) in dirname: i += 1 if i > 1: - print "Too many directories, exiting" + print("Too many directories, exiting") exit(1) xml = os.path.join("Testing", dirname, "Test.xml") return xml @@ -58,31 +59,31 @@ def find_wiki(): #find wiki and matrix file, issue 'git pull' wikipath = os.path.abspath("../../wiki-scl") if not os.path.isdir(os.path.join(wikipath,".git")): - print "Can't find wiki or not a git repo" + print("Can't find wiki or not a git repo") exit(1) p = subprocess.call(["git", "pull", "origin"], cwd=wikipath) if not p == 0: - print "'git pull' exited with error" + print("'git pull' exited with error") exit(1) matrix = os.path.join(wikipath, "Schema-build-matrix.md") if not os.path.isfile(matrix): - print "Matrix file doesn't exist or isn't a file" + print("Matrix file doesn't exist or isn't a file") exit(1) return wikipath,matrix def git_push(path,f): p = subprocess.call(["git", "add", f], cwd=path) if not p == 0: - print "'git add' exited with error" + print("'git add' exited with error") exit(1) msg = date.today().__str__() + " - schema matrix updated by update-matrix.py" p = subprocess.call(["git", "commit", "-m", msg ], cwd=path) if not p == 0: - print "'git commit' exited with error" + print("'git commit' exited with error") exit(1) p = subprocess.call(["git", "push", "origin"], cwd=path) if not p == 0: - print "'git push' exited with error" + print("'git push' exited with error") exit(1) @@ -98,8 +99,8 @@ def read_tests(xml): # read all s in xml, create mixed html/markdown try: tree = ET.parse(xml) - except Exception, inst: - print "Unexpected error opening %s: %s" % (xml, inst) + except Exception as inst: + print("Unexpected error opening %s: %s" % (xml, inst)) return root = tree.getroot() diff --git a/run_ctest.cmake b/run_ctest.cmake index 096cfb1c5..7533d7c17 100644 --- a/run_ctest.cmake +++ b/run_ctest.cmake @@ -3,8 +3,8 @@ 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_CMAKE_GENERATOR "Visual Studio 14 2015 Win64") +#set(CTEST_MEMORYCHECK_COMMAND /usr/bin/valgrind) set(CTEST_INITIAL_CACHE " SITE:STRING=${CTEST_SITE} BUILDNAME:STRING=${CTEST_BUILD_NAME} diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt deleted file mode 100644 index 6f391e7c2..000000000 --- a/src/base/CMakeLists.txt +++ /dev/null @@ -1,68 +0,0 @@ - -set(SC_BASE_SOURCES - sc_memmgr.cc - sc_trace_fprintf.c - sc_getopt.cc - sc_benchmark.cc - sc_mkdir.c - path2str.c - judy/src/judy.c - ) - -set(SC_BASE_HDRS - sc_benchmark.h - sc_memmgr.h - sc_getopt.h - sc_trace_fprintf.h - sc_mkdir.h - sc_nullptr.h - path2str.h - judy/src/judy.h - judy/src/judyLArray.h - judy/src/judyL2Array.h - judy/src/judySArray.h - judy/src/judyS2Array.h - ) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/judy/src - ) - -if(MINGW OR MSVC OR BORLAND) - add_definitions(-DSC_BASE_DLL_EXPORTS) -endif() - -if (${SC_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) -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") - -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 - diff --git a/src/base/judy/CMakeLists.txt b/src/base/judy/CMakeLists.txt deleted file mode 100644 index 4ba30087c..000000000 --- a/src/base/judy/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ - -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" ) -endif( NOT DEFINED CMAKE_BUILD_TYPE ) - -SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) -SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) -SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) - -if( NOT DEFINED JUDY_OPTIMIZE_FLAGS ) - if( CMAKE_COMPILER_IS_GNUCC ) - set( JUDY_OPTIMIZE_FLAGS "-march=native" ) - - #test for LTO; this uses an internal variable so it may break - if( DEFINED CMAKE_C_COMPILER_VERSION ) - if( ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 4.7.0 ) - set( JUDY_OPTIMIZE_FLAGS "${JUDY_OPTIMIZE_FLAGS} -flto" ) - message( " -- GCC version: ${CMAKE_C_COMPILER_VERSION}. Enabling link-time optimization." ) - endif( ${CMAKE_C_COMPILER_VERSION} VERSION_GREATER 4.7.0 ) - endif( DEFINED CMAKE_C_COMPILER_VERSION ) - #elseif( MSVC ) - # set( JUDY_OPTIMIZE_FLAGS "..." ) # <--- set MSVC flags here <--- - else() - message( "Unrecognized compiler - no optimization flags set. Edit CMakeLists.txt or set JUDY_OPTIMIZE_FLAGS." ) - set( JUDY_OPTIMIZE_FLAGS "" ) - endif( CMAKE_COMPILER_IS_GNUCC ) -endif( NOT DEFINED JUDY_OPTIMIZE_FLAGS ) -add_definitions( ${JUDY_OPTIMIZE_FLAGS} ) - -set( JUDYS_SOURCES src/judy.c src/judy.h ) - -if( CMAKE_COMPILER_IS_GNUCC ) - add_definitions( -pedantic -W -Wall -Wundef -Wfloat-equal -Wshadow -Winline -Wno-long-long ) -endif( CMAKE_COMPILER_IS_GNUCC ) - -add_library( judy_lib STATIC ${JUDYS_SOURCES} ) - -include_directories( src ) - -if( ENABLE_TESTING ) - include( CTest ) - include_directories( test ) - enable_testing() - - add_executable( pennysort test/pennySort.c test/sort.c ${JUDYS_SOURCES} ) - add_executable( hexsort test/hexSort.c test/sort.c ${JUDYS_SOURCES} ) - set_target_properties( pennysort hexsort PROPERTIES COMPILE_FLAGS "-DSTANDALONE" ) - - - add_executable( judyLtest test/judyLtest.cc ) - target_link_libraries( judyLtest judy_lib ) - add_test( judyLtest judyLtest ) - - add_executable( judyL2test test/judyL2test.cc ) - target_link_libraries( judyL2test judy_lib ) - add_test( judyL2test judyL2test ) - - add_executable( judyStest test/judyStest.cc ) - target_link_libraries( judyStest judy_lib ) - add_test( judyStest judyStest ) - - add_executable( judyS2test test/judyS2test.cc ) - target_link_libraries( judyS2test judy_lib ) - add_test( judyS2test judyS2test ) - -endif( ENABLE_TESTING ) - -# Local Variables: -# tab-width: 8 -# mode: cmake -# indent-tabs-mode: t -# End: -# ex: shiftwidth=2 tabstop=8 - diff --git a/src/base/judy/README.md b/src/base/judy/README.md deleted file mode 100644 index 5fc134587..000000000 --- a/src/base/judy/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Judy Array Templates -The Judy Array is a sparse dynamic array. It is a particular kind of trie that is highly efficient in space and time, and does not require tuning. - -This uses [Karl Malbrain's implementation](http://code.google.com/p/judyarray/) of the Judy Array. Additional information can be found with Doug Baskins' [original implementation](http://judy.sourceforge.net/) on sourceforge, or on [Wikipedia](http://en.wikipedia.org/wiki/Judy_array). -## The templates -* `judyLArray` - a C++ template wrapper for an int-int Judy Array. JudyKey and JudyValue must be integer types and the same size as a pointer (i.e. 32- or 64-bit) -* `judySArray` - Same as judyLArray, but with string-int mapping. The above restrictions on JudyValue apply here as well. -* **TODO** - single-key, multi-value versions of the above -* **TODO** - single-key, n-value versions of the above *(?)* - -## Comparison between this and the versions Karl and Doug wrote -* Doug Baskins' code is licenced under the LGPL. While more permissive than the GPL, it's still not always acceptable. His code is very fast but weighs in at ~20k lines. -* Karl Malbrain's code is ~1250 lines, in a single file containing the judy array and the test code; use requires creating a header. -* Both of the above are written in C, so they don't fit neatly into object-oriented C++. -* Unlike Doug's code, this is ~1250 lines. Unlike Karl's, this is split into several files. - -## Files -* `CMakeLists.txt` - CMake build logic. If you don't have CMake, it should be quite easy to write a file for the build system of your choice. -* **src/** - * `judy.c`, `judy.h` - implementation of the Judy Array - * `judyLArray.h` - the judyLArray template - * `judySArray.h` - the judySArray template -* **test/** - * `hexSort.c` - Sorts a file where each line contains 32 hex chars. Compiles to `hexsort`, which is the same executable as compiling Karl's code with `-DHEXSORT -DSTANDALONE` - * `pennySort.c` - Sorts strings; compiles to `pennysort`. Same as compiling Karl's code with `-DSTANDALONE`. - * `sort.c`, `sort.h` - Karl's sorting functions. Only used by `hexsort` and `pennysort`. - * `judyLtest.cc` - an incomplete test of the judyLArray template. - * `judyStest.cc` - an incomplete test of the judySArray template. - - -## Compiling -* requires C and C++ compilers, CMake. -* from the command line: - * `mkdir build; cd build` - * `cmake .. -DENABLE_TESTING=TRUE` - * `make` - -## License - -Karl Malbrain's judy array code is public domain; what I've added is public domain as well. - -## Contact -mpictor -a-t- gmail diff --git a/src/base/judy/misc/astyle.cfg b/src/base/judy/misc/astyle.cfg deleted file mode 100644 index eec1dd399..000000000 --- a/src/base/judy/misc/astyle.cfg +++ /dev/null @@ -1,29 +0,0 @@ -#astyle config file - -#run astyle on one or a few files: use -# astyle --options=misc/astyle.cfg path/to/file - -#run astyle on all files: from the root dir, use -# astyle --options=misc/astyle.cfg --recursive "src/*.c" "src/*.h" "test/*.c" "test/*.h" -# in the above line, the double quotes *are* necessary - - -suffix=none #don't create backup files - -style=java #compact bracket style - -indent=spaces=4 - -indent-preprocessor -indent-classes -indent-switches -indent-namespaces -pad-oper #pad (space) around operators -pad-paren-in #pad inside parenthesis -unpad-paren #remove parenthesis padding other than requested above - -add-brackets #add brackets on one-line conditionals -convert-tabs #convert all tabs to spaces -align-pointer=middle #char * foo - -lineend=linux #lines end with LF (linux), not CRLF (windows) diff --git a/src/base/judy/misc/hextest.sh b/src/base/judy/misc/hextest.sh deleted file mode 100755 index ee8606d48..000000000 --- a/src/base/judy/misc/hextest.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh - -#generates a file of hex keys and runs hexsort on it. No verification is done. -#hex data comes from /dev/urandom, so it isn't all that random. - -hexdump -v -e '2/8 "%08x"' -e '"\n"' /dev/urandom |head -n 1000000 >ukeys -#a.out [in-file] [out-file] [keysize] [recordlen] [keyoffset] [mergerecs] -time bin/hexsort ukeys skeys \ No newline at end of file diff --git a/src/base/judy/misc/judy64n.c b/src/base/judy/misc/judy64n.c deleted file mode 100644 index 8dc8f909a..000000000 --- a/src/base/judy/misc/judy64n.c +++ /dev/null @@ -1,2084 +0,0 @@ -// Judy arrays 23 NOV 2012 - -// Author Karl Malbrain, malbrain@yahoo.com -// with assistance from Jan Weiss. - -// Simplified judy arrays for strings and integers -// Adapted from the ideas of Douglas Baskins of HP. - -// The -D ASKITIS benchmarking option was implemented with -// assistance from Dr. Nikolas Askitis (www.naskitis.com). - -// Map a set of keys to corresponding memory cells (unsigned ints). -// Each cell must be set to a non-zero value by the caller. - -// STANDALONE is defined to compile into a string sorter. - -// String mappings are denoted by calling judy_open with zero as -// the second argument. Integer mappings are denoted by calling -// judy_open with the Integer depth of the Judy Trie as the second -// argument. - -//#define STANDALONE - -// functions: -// judy_open: open a new judy array returning a judy object. -// judy_close: close an open judy array, freeing all memory. -// judy_clone: clone an open judy array, duplicating the stack. -// judy_data: allocate data memory within judy array for external use. -// judy_cell: insert a string into the judy array, return cell pointer. -// judy_strt: retrieve the cell pointer greater than or equal to given key -// judy_slot: retrieve the cell pointer, or return NULL for a given key. -// judy_key: retrieve the string value for the most recent judy query. -// judy_end: retrieve the cell pointer for the last string in the array. -// judy_nxt: retrieve the cell pointer for the next string in the array. -// judy_prv: retrieve the cell pointer for the prev string in the array. -// judy_del: delete the key and cell for the current stack entry. - -#include -#include -#include - -#ifdef linux - #define _FILE_OFFSET_BITS 64 - #define _LARGEFILE_SOURCE - #define __USE_FILE_OFFSET64 - - #include -#else - #ifdef __BIG_ENDIAN__ - #ifndef BYTE_ORDER - #define BYTE_ORDER 4321 - #endif - #else - #ifndef BYTE_ORDER - #define BYTE_ORDER 1234 - #endif - #endif - #ifndef BIG_ENDIAN - #define BIG_ENDIAN 4321 - #endif -#endif - - - -#define PRIuint "u" - -#if defined(__LP64__) || \ - defined(__x86_64__) || \ - defined(__amd64__) || \ - defined(_WIN64) || \ - defined(__sparc64__) || \ - defined(__arch64__) || \ - defined(__powerpc64__) || \ - defined (__s390x__) - // defines for 64 bit - - typedef unsigned long long judyvalue; - typedef unsigned long long JudySlot; - #define JUDY_key_mask (0x07) - #define JUDY_key_size 8 - #define JUDY_slot_size 8 - #define JUDY_span_bytes (3 * JUDY_key_size) - #define JUDY_span_equiv JUDY_2 - #define JUDY_radix_equiv JUDY_8 - - #define PRIjudyvalue "llu" - -#else - // defines for 32 bit - - typedef unsigned int judyvalue; - typedef unsigned int JudySlot; - #define JUDY_key_mask (0x03) - #define JUDY_key_size 4 - #define JUDY_slot_size 4 - #define JUDY_span_bytes (7 * JUDY_key_size) - #define JUDY_span_equiv JUDY_4 - #define JUDY_radix_equiv JUDY_8 - - #define PRIjudyvalue "u" - -#endif - -#define JUDY_mask (~(JudySlot)0x07) - -// define the alignment factor for judy nodes and allocations -// to enable this feature, set to 64 - -#define JUDY_cache_line 8 // minimum size is 8 bytes - -#if defined(STANDALONE) || defined(ASKITIS) -#include -#include - -unsigned int MaxMem = 0; - -// void judy_abort (char *msg) __attribute__ ((noreturn)); // Tell static analyser that this function will not return -void judy_abort (char *msg) -{ - fprintf(stderr, "%s\n", msg); - exit(1); -} -#endif - -#define JUDY_seg 65536 - -enum JUDY_types { - JUDY_radix = 0, // inner and outer radix fan-out - JUDY_1 = 1, // linear list nodes of designated count - JUDY_2 = 2, - JUDY_4 = 3, - JUDY_8 = 4, - JUDY_16 = 5, - JUDY_32 = 6, -#ifdef ASKITIS - JUDY_64 = 7 -#else - JUDY_span = 7 // up to 28 tail bytes of key contiguously stored -#endif -}; - -int JudySize[] = { - (JUDY_slot_size * 16), // JUDY_radix node size - (JUDY_slot_size + JUDY_key_size), // JUDY_1 node size - (2 * JUDY_slot_size + 2 * JUDY_key_size), - (4 * JUDY_slot_size + 4 * JUDY_key_size), - (8 * JUDY_slot_size + 8 * JUDY_key_size), - (16 * JUDY_slot_size + 16 * JUDY_key_size), - (32 * JUDY_slot_size + 32 * JUDY_key_size), -#ifndef ASKITIS - (JUDY_span_bytes + JUDY_slot_size) -#else - (64 * JUDY_slot_size + 64 * JUDY_key_size) -#endif -}; - -judyvalue JudyMask[9] = { -0, 0xff, 0xffff, 0xffffff, 0xffffffff, -#if JUDY_key_size > 4 -0xffffffffffULL, 0xffffffffffffULL, 0xffffffffffffffULL, 0xffffffffffffffffULL -#endif -}; - -typedef struct { - void *seg; // next used allocator - unsigned int next; // next available offset -} JudySeg; - -typedef struct { - JudySlot next; // judy object - unsigned int off; // offset within key - int slot; // slot within object -} JudyStack; - -typedef struct { - JudySlot root[1]; // root of judy array - void **reuse[8]; // reuse judy blocks - JudySeg *seg; // current judy allocator - unsigned int level; // current height of stack - unsigned int max; // max height of stack - unsigned int depth; // number of Integers in a key, or zero for string keys - JudyStack stack[1]; // current cursor -} Judy; - -#ifdef ASKITIS -int Words = 0; -int Inserts = 0; -int Found = 0; - -#if JUDY_key_size < 8 -#define JUDY_max JUDY_16 -#else -#define JUDY_max JUDY_64 -#endif -#else -#define JUDY_max JUDY_32 -#endif - -// open judy object -// call with max key size -// and Integer tree depth. - -void *judy_open (unsigned int max, unsigned int depth) -{ -JudySeg *seg; -Judy *judy; -unsigned int amt; - - max++; // allow for zero terminator on keys - - if( (seg = malloc(JUDY_seg)) ) { - seg->seg = NULL; - seg->next = JUDY_seg; - } else { -#if defined(STANDALONE) || defined(ASKITIS) - judy_abort ("No virtual memory"); -#else - return NULL; -#endif - } - - amt = sizeof(Judy) + max * sizeof(JudyStack); - - if( amt & (JUDY_cache_line - 1) ) - amt |= JUDY_cache_line - 1, amt++; - -#if defined(STANDALONE) || defined(ASKITIS) - MaxMem += JUDY_seg; -#endif - - seg->next -= (JudySlot)seg & (JUDY_cache_line - 1); - seg->next -= amt; - - judy = (Judy *)((unsigned char *)seg + seg->next); - memset(judy, 0, amt); - judy->depth = depth; - judy->seg = seg; - judy->max = max; - return judy; -} - -void judy_close (Judy *judy) -{ -JudySeg *seg, *nxt = judy->seg; - - while( (seg = nxt) ) - nxt = seg->seg, free (seg); -} - -// allocate judy node - -void *judy_alloc (Judy *judy, unsigned int type) -{ -unsigned int amt, idx, min; -JudySeg *seg; -void **block; -void **rtn; - - if( !judy->seg ) -#if defined(STANDALONE) || defined(ASKITIS) - judy_abort("illegal allocation from judy clone"); -#else - return NULL; -#endif - - if( type == JUDY_radix ) - type = JUDY_radix_equiv; - -#ifndef ASKITIS - if( type == JUDY_span ) - type = JUDY_span_equiv; -#endif - - amt = JudySize[type]; - - if( amt & 0x07 ) - amt |= 0x07, amt += 1; - - // see if free block is already available - - if( (block = judy->reuse[type]) ) { - judy->reuse[type] = *block; - memset (block, 0, amt); - return (void *)block; - } - - // break down available larger block - // for reuse into smaller blocks - - if( type >= JUDY_1 ) - for( idx = type; idx++ < JUDY_max; ) - if( block = judy->reuse[idx] ) { - judy->reuse[idx] = *block; - while( idx-- > type) { - judy->reuse[idx] = block + JudySize[idx] / sizeof(void *); - block[JudySize[idx] / sizeof(void *)] = 0; - } - memset (block, 0, amt); - return (void *)block; - } - - min = amt < JUDY_cache_line ? JUDY_cache_line : amt; - - if( judy->seg->next < min + sizeof(*seg) ) { - if( (seg = malloc (JUDY_seg)) ) { - seg->next = JUDY_seg; - seg->seg = judy->seg; - judy->seg = seg; - seg->next -= (JudySlot)seg & (JUDY_cache_line - 1); - } else { -#if defined(STANDALONE) || defined(ASKITIS) - judy_abort("Out of virtual memory"); -#else - return NULL; -#endif - } - -#if defined(STANDALONE) || defined(ASKITIS) - MaxMem += JUDY_seg; -#endif - } - - // generate additional free blocks - // to fill up to cache line size - - rtn = (void **)((unsigned char *)judy->seg + judy->seg->next - amt); - - for( idx = type; amt & (JUDY_cache_line - 1); amt <<= 1 ) { - block = (void **)((unsigned char *)judy->seg + judy->seg->next - 2 * amt); - judy->reuse[idx++] = block; - *block = 0; - } - - judy->seg->next -= amt; - memset (rtn, 0, JudySize[type]); - return (void *)rtn; -} - -void *judy_data (Judy *judy, unsigned int amt) - -{ -JudySeg *seg; -void *block; - - if( !judy->seg ) -#if defined(STANDALONE) || defined(ASKITIS) - judy_abort("illegal allocation from judy clone"); -#else - return NULL; -#endif - - if( amt & (JUDY_cache_line - 1)) - amt |= (JUDY_cache_line - 1), amt += 1; - - if( judy->seg->next < amt + sizeof(*seg) ) { - if( (seg = malloc (JUDY_seg)) ) { - seg->next = JUDY_seg; - seg->seg = judy->seg; - judy->seg = seg; - seg->next -= (JudySlot)seg & (JUDY_cache_line - 1); - } else { -#if defined(STANDALONE) || defined(ASKITIS) - judy_abort("Out of virtual memory"); -#else - return NULL; -#endif - } - -#if defined(STANDALONE) || defined(ASKITIS) - MaxMem += JUDY_seg; -#endif - } - - judy->seg->next -= amt; - - block = (void *)((unsigned char *)judy->seg + judy->seg->next); - memset (block, 0, amt); - return block; -} - -void *judy_clone (Judy *judy) -{ -Judy *clone; -unsigned int amt; - - amt = sizeof(Judy) + judy->max * sizeof(JudyStack); - clone = judy_data (judy, amt); - memcpy (clone, judy, amt); - clone->seg = NULL; // stop allocations from cloned array - return clone; -} - -void judy_free (Judy *judy, void *block, int type) -{ - if( type == JUDY_radix ) - type = JUDY_radix_equiv; - -#ifndef ASKITIS - if( type == JUDY_span ) - type = JUDY_span_equiv; -#endif - - *((void **)(block)) = judy->reuse[type]; - judy->reuse[type] = (void **)block; - return; -} - -// assemble key from current path - -unsigned int judy_key (Judy *judy, unsigned char *buff, unsigned int max) -{ -judyvalue *dest = (judyvalue *)buff; -unsigned int len = 0, idx = 0, depth; -int slot, off, type; -judyvalue value; -unsigned char *base; -int keysize; - - if( judy->depth ) - max = judy->depth * JUDY_key_size; - else - max--; // leave room for zero terminator - - while( len < max && ++idx <= judy->level ) { - type = judy->stack[idx].next & 0x07; - slot = judy->stack[idx].slot; - depth = len / JUDY_key_size; - - if( judy->depth ) - if( !(len & JUDY_key_mask) ) - dest[depth] = 0; - - switch( type ) { - case JUDY_1: - case JUDY_2: - case JUDY_4: - case JUDY_8: - case JUDY_16: - case JUDY_32: -#ifdef ASKITIS - case JUDY_64: -#endif - keysize = JUDY_key_size - (judy->stack[idx].off & JUDY_key_mask); - base = (unsigned char *)(judy->stack[idx].next & JUDY_mask); - - if( judy->depth ) { - value = *(judyvalue *)(base + slot * keysize); - value &= JudyMask[keysize]; - dest[depth++] |= value; - len += keysize; - - if( depth < judy->depth ) - continue; - - return len; - } - -#if BYTE_ORDER != BIG_ENDIAN - off = keysize; - - while( off-- && len < max ) - if( buff[len] = base[slot * keysize + off] ) - len++; - else - break; -#else - for( off = 0; off < keysize && len < max; off++ ) - if( buff[len] = base[slot * keysize + off] ) - len++; - else - break; -#endif - continue; - - case JUDY_radix: - if( judy->depth ) { - dest[depth] |= (judyvalue)slot << (JUDY_key_size - (++len & JUDY_key_mask)) * 8; - if( !(len & JUDY_key_mask) ) - depth++; - if( depth < judy->depth ) - continue; - - return len; - } - - if( !slot ) - break; - buff[len++] = (unsigned char)slot; - continue; - -#ifndef ASKITIS - case JUDY_span: - base = (unsigned char *)(judy->stack[idx].next & JUDY_mask); - - for( slot = 0; slot < JUDY_span_bytes && base[slot]; slot++ ) - if( len < max ) - buff[len++] = base[slot]; - continue; -#endif - } - } - buff[len] = 0; - return len; -} - -// find slot & setup cursor - -JudySlot *judy_slot (Judy *judy, unsigned char *buff, unsigned int max) -{ -judyvalue *src = (judyvalue *)buff; -int slot, size, keysize, tst, cnt; -JudySlot next = *judy->root; -judyvalue value, test = 0; -JudySlot *table; -JudySlot *node; -unsigned int depth = 0; -unsigned int off = 0; -unsigned char *base; - -#ifndef ASKITIS - judy->level = 0; -#endif - - while( next ) { -#ifndef ASKITIS - if( judy->level < judy->max ) - judy->level++; - - judy->stack[judy->level].next = next; - judy->stack[judy->level].off = off; -#endif - size = JudySize[next & 0x07]; - - switch( next & 0x07 ) { - - case JUDY_1: - case JUDY_2: - case JUDY_4: - case JUDY_8: - case JUDY_16: - case JUDY_32: -#ifdef ASKITIS - case JUDY_64: -#endif - base = (unsigned char *)(next & JUDY_mask); - node = (JudySlot *)((next & JUDY_mask) + size); - keysize = JUDY_key_size - (off & JUDY_key_mask); - cnt = size / (sizeof(JudySlot) + keysize); - slot = cnt; - value = 0; - - if( judy->depth ) { - value = src[depth++]; - off |= JUDY_key_mask; - off++; - value &= JudyMask[keysize]; - } else - do { - value <<= 8; - if( off < max ) - value |= buff[off]; - } while( ++off & JUDY_key_mask ); - - // find slot > key - - while( slot-- ) { - test = *(judyvalue *)(base + slot * keysize); -#if BYTE_ORDER == BIG_ENDIAN - test >>= 8 * (JUDY_key_size - keysize); -#else - test &= JudyMask[keysize]; -#endif - if( test <= value ) - break; - } -#ifndef ASKITIS - judy->stack[judy->level].slot = slot; -#endif - if( test == value ) { - - // is this a leaf? - - if( !judy->depth && !(value & 0xFF) || judy->depth && depth == judy->depth ) - return &node[-slot-1]; - - next = node[-slot-1]; - continue; - } - - return NULL; - - case JUDY_radix: - table = (JudySlot *)(next & JUDY_mask); // outer radix - - if( judy->depth ) - slot = (src[depth] >> ((JUDY_key_size - off++ & JUDY_key_mask) * 8)) & 0xff; - else if( off < max ) - slot = buff[off++]; - else - slot = 0; -#ifndef ASKITIS - // put radix slot on judy stack - - judy->stack[judy->level].slot = slot; -#endif - if( (next = table[slot >> 4]) ) - table = (JudySlot *)(next & JUDY_mask); // inner radix - else - return NULL; - - if( judy->depth ) - if( !(off & JUDY_key_mask) ) - depth++; - - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) // leaf? - if( table[slot & 0x0F] ) // occupied? - return &table[slot & 0x0F]; - else - return NULL; - - next = table[slot & 0x0F]; - continue; - -#ifndef ASKITIS - case JUDY_span: - node = (JudySlot *)((next & JUDY_mask) + JudySize[JUDY_span]); - base = (unsigned char *)(next & JUDY_mask); - cnt = tst = JUDY_span_bytes; - if( tst > (int)(max - off) ) - tst = max - off; - value = strncmp((const char *)base, (const char *)(buff + off), tst); - if( !value && tst < cnt && !base[tst] ) // leaf? - return &node[-1]; - - if( !value && tst == cnt ) { - next = node[-1]; - off += cnt; - continue; - } - return NULL; -#endif - } - } - - return NULL; -} - -// promote full nodes to next larger size - -JudySlot *judy_promote (Judy *judy, JudySlot *next, int idx, judyvalue value, int keysize) -{ -unsigned char *base = (unsigned char *)(*next & JUDY_mask); -int oldcnt, newcnt, slot; -#if BYTE_ORDER == BIG_ENDIAN - int i; -#endif -JudySlot *newnode, *node; -JudySlot *result; -unsigned char *newbase; -unsigned int type; - - type = (*next & 0x07) + 1; - node = (JudySlot *)((*next & JUDY_mask) + JudySize[type-1]); - oldcnt = JudySize[type-1] / (sizeof(JudySlot) + keysize); - newcnt = JudySize[type] / (sizeof(JudySlot) + keysize); - - // promote node to next larger size - - newbase = judy_alloc (judy, type); - newnode = (JudySlot *)(newbase + JudySize[type]); - *next = (JudySlot)newbase | type; - - // open up slot at idx - - memcpy(newbase + (newcnt - oldcnt - 1) * keysize, base, idx * keysize); // copy keys - - for( slot = 0; slot < idx; slot++ ) - newnode[-(slot + newcnt - oldcnt)] = node[-(slot + 1)]; // copy ptr - - // fill in new node - -#if BYTE_ORDER != BIG_ENDIAN - memcpy(newbase + (idx + newcnt - oldcnt - 1) * keysize, &value, keysize); // copy key -#else - i = keysize; - - while( i-- ) - newbase[(idx + newcnt - oldcnt - 1) * keysize + i] = value, value >>= 8; -#endif - result = &newnode[-(idx + newcnt - oldcnt)]; - - // copy rest of old node - - memcpy(newbase + (idx + newcnt - oldcnt) * keysize, base + (idx * keysize), (oldcnt - slot) * keysize); // copy keys - - for( ; slot < oldcnt; slot++ ) - newnode[-(slot + newcnt - oldcnt + 1)] = node[-(slot + 1)]; // copy ptr - -#ifndef ASKITIS - judy->stack[judy->level].next = *next; - judy->stack[judy->level].slot = idx + newcnt - oldcnt - 1; -#endif - judy_free (judy, (void **)base, type - 1); - return result; -} - -// construct new node for JUDY_radix entry -// make node with slot - start entries -// moving key over one offset - -void judy_radix (Judy *judy, JudySlot *radix, unsigned char *old, int start, int slot, int keysize, unsigned char key, unsigned int depth) -{ -int size, idx, cnt = slot - start, newcnt; -JudySlot *node, *oldnode; -unsigned int type = JUDY_1 - 1; -JudySlot *table; -unsigned char *base; - - // if necessary, setup inner radix node - - if( !(table = (JudySlot *)(radix[key >> 4] & JUDY_mask)) ) { - table = judy_alloc (judy, JUDY_radix); - radix[key >> 4] = (JudySlot)table | JUDY_radix; - } - - oldnode = (JudySlot *)(old + JudySize[JUDY_max]); - - // is this slot a leaf? - - if( !judy->depth && (!key || !keysize) || judy->depth && !keysize && depth == judy->depth) { - table[key & 0x0F] = oldnode[-start-1]; - return; - } - - // calculate new node big enough to contain slots - - do { - type++; - size = JudySize[type]; - newcnt = size / (sizeof(JudySlot) + keysize); - } while( cnt > newcnt && type < JUDY_max ); - - // store new node pointer in inner table - - base = judy_alloc (judy, type); - node = (JudySlot *)(base + size); - table[key & 0x0F] = (JudySlot)base | type; - - // allocate node and copy old contents - // shorten keys by 1 byte during copy - - for( idx = 0; idx < cnt; idx++ ) { -#if BYTE_ORDER != BIG_ENDIAN - memcpy (base + (newcnt - idx - 1) * keysize, old + (start + cnt - idx - 1) * (keysize + 1), keysize); -#else - memcpy (base + (newcnt - idx - 1) * keysize, old + (start + cnt - idx - 1) * (keysize + 1) + 1, keysize); -#endif - node[-(newcnt - idx)] = oldnode[-(start + cnt - idx)]; - } -} - -// decompose full node to radix nodes - -void judy_splitnode (Judy *judy, JudySlot *next, unsigned int size, unsigned int keysize, unsigned int depth) -{ -int cnt, slot, start = 0; -unsigned int key = 0x0100, nxt; -JudySlot *newradix; -unsigned char *base; - - base = (unsigned char *)(*next & JUDY_mask); - cnt = size / (sizeof(JudySlot) + keysize); - - // allocate outer judy_radix node - - newradix = judy_alloc (judy, JUDY_radix); - *next = (JudySlot)newradix | JUDY_radix; - - for( slot = 0; slot < cnt; slot++ ) { -#if BYTE_ORDER != BIG_ENDIAN - nxt = base[slot * keysize + keysize - 1]; -#else - nxt = base[slot * keysize]; -#endif - - if( key > 0xFF ) - key = nxt; - if( nxt == key ) - continue; - - // decompose portion of old node into radix nodes - - judy_radix (judy, newradix, base, start, slot, keysize - 1, (unsigned char)key, depth); - start = slot; - key = nxt; - } - - judy_radix (judy, newradix, base, start, slot, keysize - 1, (unsigned char)key, depth); - judy_free (judy, (void **)base, JUDY_max); -} - -// return first leaf - -JudySlot *judy_first (Judy *judy, JudySlot next, unsigned int off, unsigned int depth) -{ -JudySlot *table, *inner; -unsigned int keysize, size; -JudySlot *node; -int slot, cnt; -unsigned char *base; - - while( next ) { - if( judy->level < judy->max ) - judy->level++; - - judy->stack[judy->level].off = off; - judy->stack[judy->level].next = next; - size = JudySize[next & 0x07]; - - switch( next & 0x07 ) { - case JUDY_1: - case JUDY_2: - case JUDY_4: - case JUDY_8: - case JUDY_16: - case JUDY_32: -#ifdef ASKITIS - case JUDY_64: -#endif - keysize = JUDY_key_size - (off & JUDY_key_mask); - node = (JudySlot *)((next & JUDY_mask) + size); - base = (unsigned char *)(next & JUDY_mask); - cnt = size / (sizeof(JudySlot) + keysize); - - for( slot = 0; slot < cnt; slot++ ) - if( node[-slot-1] ) - break; - - judy->stack[judy->level].slot = slot; -#if BYTE_ORDER != BIG_ENDIAN - if( !judy->depth && !base[slot * keysize] || judy->depth && ++depth == judy->depth ) - return &node[-slot-1]; -#else - if( !judy->depth && !base[slot * keysize + keysize - 1] || judy->depth && ++depth == judy->depth ) - return &node[-slot-1]; -#endif - next = node[-slot - 1]; - off = (off | JUDY_key_mask) + 1; - continue; - case JUDY_radix: - off++; - - if( judy->depth ) - if( !(off & JUDY_key_mask) ) - depth++; - - table = (JudySlot *)(next & JUDY_mask); - for( slot = 0; slot < 256; slot++ ) - if( (inner = (JudySlot *)(table[slot >> 4] & JUDY_mask)) ) { - if( (next = inner[slot & 0x0F]) ) { - judy->stack[judy->level].slot = slot; - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) - return &inner[slot & 0x0F]; - else - break; - } - } else - slot |= 0x0F; - continue; -#ifndef ASKITIS - case JUDY_span: - node = (JudySlot *)((next & JUDY_mask) + JudySize[JUDY_span]); - base = (unsigned char *)(next & JUDY_mask); - cnt = JUDY_span_bytes; - if( !base[cnt - 1] ) // leaf node? - return &node[-1]; - next = node[-1]; - off += cnt; - continue; -#endif - } - } - return NULL; -} - -// return last leaf cell pointer - -JudySlot *judy_last (Judy *judy, JudySlot next, unsigned int off, unsigned int depth) -{ -JudySlot *table, *inner; -unsigned int keysize, size; -JudySlot *node; -int slot, cnt; -unsigned char *base; - - while( next ) { - if( judy->level < judy->max ) - judy->level++; - - judy->stack[judy->level].next = next; - judy->stack[judy->level].off = off; - size = JudySize[next & 0x07]; - switch( next & 0x07 ) { - case JUDY_1: - case JUDY_2: - case JUDY_4: - case JUDY_8: - case JUDY_16: - case JUDY_32: -#ifdef ASKITIS - case JUDY_64: -#endif - keysize = JUDY_key_size - (off & JUDY_key_mask); - slot = size / (sizeof(JudySlot) + keysize); - base = (unsigned char *)(next & JUDY_mask); - node = (JudySlot *)((next & JUDY_mask) + size); - judy->stack[judy->level].slot = --slot; - -#if BYTE_ORDER != BIG_ENDIAN - if( !judy->depth && !base[slot * keysize] || judy->depth && ++depth == judy->depth ) -#else - if( !judy->depth && !base[slot * keysize + keysize - 1] || judy->depth && ++depth == judy->depth ) -#endif - return &node[-slot-1]; - - next = node[-slot-1]; - off += keysize; - continue; - - case JUDY_radix: - table = (JudySlot *)(next & JUDY_mask); - off++; - - if( judy->depth ) - if( !(off & JUDY_key_mask) ) - depth++; - - for( slot = 256; slot--; ) { - judy->stack[judy->level].slot = slot; - if( (inner = (JudySlot *)(table[slot >> 4] & JUDY_mask)) ) { - if( (next = inner[slot & 0x0F]) ) - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) - return &inner[0]; - else - break; - } else - slot &= 0xF0; - } - continue; - -#ifndef ASKITIS - case JUDY_span: - node = (JudySlot *)((next & JUDY_mask) + JudySize[JUDY_span]); - base = (unsigned char *)(next & JUDY_mask); - cnt = JUDY_span_bytes; - if( !base[cnt - 1] ) // leaf node? - return &node[-1]; - next = node[-1]; - off += cnt; - continue; -#endif - } - } - return NULL; -} - -// judy_end: return last entry - -JudySlot *judy_end (Judy *judy) -{ - judy->level = 0; - return judy_last (judy, *judy->root, 0, 0); -} // judy_nxt: return next entry - -JudySlot *judy_nxt (Judy *judy) -{ -JudySlot *table, *inner; -int slot, size, cnt; -JudySlot *node; -JudySlot next; -unsigned int keysize; -unsigned char *base; -unsigned int depth; -unsigned int off; - - if( !judy->level ) - return judy_first (judy, *judy->root, 0, 0); - - while( judy->level ) { - next = judy->stack[judy->level].next; - slot = judy->stack[judy->level].slot; - off = judy->stack[judy->level].off; - keysize = JUDY_key_size - (off & JUDY_key_mask); - size = JudySize[next & 0x07]; - depth = off / JUDY_key_size; - - switch( next & 0x07 ) { - case JUDY_1: - case JUDY_2: - case JUDY_4: - case JUDY_8: - case JUDY_16: - case JUDY_32: -#ifdef ASKITIS - case JUDY_64: -#endif - cnt = size / (sizeof(JudySlot) + keysize); - node = (JudySlot *)((next & JUDY_mask) + size); - base = (unsigned char *)(next & JUDY_mask); - if( ++slot < cnt ) -#if BYTE_ORDER != BIG_ENDIAN - if( !judy->depth && !base[slot * keysize] || judy->depth && ++depth == judy->depth ) -#else - if( !judy->depth && !base[slot * keysize + keysize - 1] || judy->depth && ++depth == judy->depth ) -#endif - { - judy->stack[judy->level].slot = slot; - return &node[-slot - 1]; - } else { - judy->stack[judy->level].slot = slot; - return judy_first (judy, node[-slot-1], (off | JUDY_key_mask) + 1, depth); - } - judy->level--; - continue; - - case JUDY_radix: - table = (JudySlot *)(next & JUDY_mask); - - if( judy->depth ) - if( !((off+1) & JUDY_key_mask) ) - depth++; - - while( ++slot < 256 ) - if( (inner = (JudySlot *)(table[slot >> 4] & JUDY_mask)) ) { - if( inner[slot & 0x0F] ) { - judy->stack[judy->level].slot = slot; - if( !judy->depth || depth < judy->depth ) - return judy_first(judy, inner[slot & 0x0F], off + 1, depth); - return &inner[slot & 0x0F]; - } - } else - slot |= 0x0F; - - judy->level--; - continue; -#ifndef ASKITIS - case JUDY_span: - judy->level--; - continue; -#endif - } - } - return NULL; -} - -// judy_prv: return ptr to previous entry - -JudySlot *judy_prv (Judy *judy) -{ -int slot, size, keysize; -JudySlot *table, *inner; -JudySlot *node, next; -unsigned char *base; -unsigned int depth; -unsigned int off; - - if( !judy->level ) - return judy_last (judy, *judy->root, 0, 0); - - while( judy->level ) { - next = judy->stack[judy->level].next; - slot = judy->stack[judy->level].slot; - off = judy->stack[judy->level].off; - size = JudySize[next & 0x07]; - depth = off / JUDY_key_size; - - switch( next & 0x07 ) { - case JUDY_1: - case JUDY_2: - case JUDY_4: - case JUDY_8: - case JUDY_16: - case JUDY_32: -#ifdef ASKITIS - case JUDY_64: -#endif - node = (JudySlot *)((next & JUDY_mask) + size); - if( !slot || !node[-slot] ) { - judy->level--; - continue; - } - - base = (unsigned char *)(next & JUDY_mask); - judy->stack[judy->level].slot--; - keysize = JUDY_key_size - (off & JUDY_key_mask); - -#if BYTE_ORDER != BIG_ENDIAN - if( !judy->depth && !base[(slot - 1) * keysize] || judy->depth && ++depth == judy->depth ) -#else - if( !judy->depth && !base[(slot - 1) * keysize + keysize - 1] || judy->depth && ++depth == judy->depth ) -#endif - return &node[-slot]; - return judy_last (judy, node[-slot], (off | JUDY_key_mask) + 1, depth); - - case JUDY_radix: - table = (JudySlot *)(next & JUDY_mask); - - if( judy->depth ) - if( !((off + 1) & JUDY_key_mask) ) - depth++; - - while( slot-- ) { - judy->stack[judy->level].slot--; - if( (inner = (JudySlot *)(table[slot >> 4] & JUDY_mask)) ) - if( inner[slot & 0x0F] ) - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) - return &inner[0]; - else - return judy_last(judy, inner[slot & 0x0F], off + 1, depth); - } - - judy->level--; - continue; - -#ifndef ASKITIS - case JUDY_span: - judy->level--; - continue; -#endif - } - } - return NULL; -} - -// judy_del: delete string from judy array -// returning previous entry. - -JudySlot *judy_del (Judy *judy) -{ -int slot, off, size, type, high; -JudySlot *table, *inner; -JudySlot next, *node; -int keysize, cnt; -unsigned char *base; - - while( judy->level ) { - next = judy->stack[judy->level].next; - slot = judy->stack[judy->level].slot; - off = judy->stack[judy->level].off; - size = JudySize[next & 0x07]; - - switch( type = next & 0x07 ) { - case JUDY_1: - case JUDY_2: - case JUDY_4: - case JUDY_8: - case JUDY_16: - case JUDY_32: -#ifdef ASKITIS - case JUDY_64: -#endif - keysize = JUDY_key_size - (off & JUDY_key_mask); - cnt = size / (sizeof(JudySlot) + keysize); - node = (JudySlot *)((next & JUDY_mask) + size); - base = (unsigned char *)(next & JUDY_mask); - - // move deleted slot to first slot - - while( slot ) { - node[-slot-1] = node[-slot]; - memcpy (base + slot * keysize, base + (slot - 1) * keysize, keysize); - slot--; - } - - // zero out first slot - - node[-1] = 0; - memset (base, 0, keysize); - - if( node[-cnt] ) { // does node have any slots left? - judy->stack[judy->level].slot++; - return judy_prv (judy); - } - - judy_free (judy, base, type); - judy->level--; - continue; - - case JUDY_radix: - table = (JudySlot *)(next & JUDY_mask); - inner = (JudySlot *)(table[slot >> 4] & JUDY_mask); - inner[slot & 0x0F] = 0; - high = slot & 0xF0; - - for( cnt = 16; cnt--; ) - if( inner[cnt] ) - return judy_prv (judy); - - judy_free (judy, inner, JUDY_radix); - table[slot >> 4] = 0; - - for( cnt = 16; cnt--; ) - if( table[cnt] ) - return judy_prv (judy); - - judy_free (judy, table, JUDY_radix); - judy->level--; - continue; - -#ifndef ASKITIS - case JUDY_span: - base = (unsigned char *)(next & JUDY_mask); - judy_free (judy, base, type); - judy->level--; - continue; -#endif - } - } - - // tree is now empty - - *judy->root = 0; - return NULL; -} - -// return cell for first key greater than or equal to given key - -JudySlot *judy_strt (Judy *judy, unsigned char *buff, unsigned int max) -{ -JudySlot *cell; - - judy->level = 0; - - if( !max ) - return judy_first (judy, *judy->root, 0, 0); - - if( (cell = judy_slot (judy, buff, max)) ) - return cell; - - return judy_nxt (judy); -} - -// split open span node - -#ifndef ASKITIS -void judy_splitspan (Judy *judy, JudySlot *next, unsigned char *base) -{ -JudySlot *node = (JudySlot *)(base + JudySize[JUDY_span]); -unsigned int cnt = JUDY_span_bytes; -unsigned char *newbase; -unsigned int off = 0; -#if BYTE_ORDER != BIG_ENDIAN -int i; -#endif - - do { - newbase = judy_alloc (judy, JUDY_1); - *next = (JudySlot)newbase | JUDY_1; - -#if BYTE_ORDER != BIG_ENDIAN - i = JUDY_key_size; - while( i-- ) - *newbase++ = base[off + i]; -#else - memcpy (newbase, base + off, JUDY_key_size); - newbase += JUDY_key_size; -#endif - next = (JudySlot *)newbase; - - off += JUDY_key_size; - cnt -= JUDY_key_size; - } while( cnt && base[off - 1] ); - - *next = node[-1]; - judy_free (judy, base, JUDY_span); -} -#endif - -// judy_cell: add string to judy array - -JudySlot *judy_cell (Judy *judy, unsigned char *buff, unsigned int max) -{ -judyvalue *src = (judyvalue *)buff; -int size, idx, slot, cnt, tst; -JudySlot *next = judy->root; -judyvalue test, value; -unsigned int off = 0, start; -JudySlot *table; -JudySlot *node; -unsigned int depth = 0; -unsigned int keysize; -unsigned char *base; - - judy->level = 0; -#ifdef ASKITIS - Words++; -#endif - - while( *next ) { -#ifndef ASKITIS - if( judy->level < judy->max ) - judy->level++; - - judy->stack[judy->level].next = *next; - judy->stack[judy->level].off = off; -#endif - switch( *next & 0x07 ) { - default: - size = JudySize[*next & 0x07]; - keysize = JUDY_key_size - (off & JUDY_key_mask); - cnt = size / (sizeof(JudySlot) + keysize); - base = (unsigned char *)(*next & JUDY_mask); - node = (JudySlot *)((*next & JUDY_mask) + size); - start = off; - slot = cnt; - value = 0; - - if( judy->depth ) { - value = src[depth++]; - off |= JUDY_key_mask; - off++; - value &= JudyMask[keysize]; - } else - do { - value <<= 8; - if( off < max ) - value |= buff[off]; - } while( ++off & JUDY_key_mask ); - - // find slot > key - - while( slot-- ) { - test = *(judyvalue *)(base + slot * keysize); -#if BYTE_ORDER == BIG_ENDIAN - test >>= 8 * (JUDY_key_size - keysize); -#else - test &= JudyMask[keysize]; -#endif - if( test <= value ) - break; - } -#ifndef ASKITIS - judy->stack[judy->level].slot = slot; -#endif - if( test == value ) { // new key is equal to slot key - next = &node[-slot-1]; - - // is this a leaf? - - if( !judy->depth && !(value & 0xFF) || judy->depth && depth == judy->depth ) { -#ifdef ASKITIS - if( *next ) - Found++; - else - Inserts++; -#endif - return next; - } - - continue; - } - - // if this node is not full - // open up cell after slot - - if( !node[-1] ) { - memmove(base, base + keysize, slot * keysize); // move keys less than new key down one slot -#if BYTE_ORDER != BIG_ENDIAN - memcpy(base + slot * keysize, &value, keysize); // copy new key into slot -#else - test = value; - idx = keysize; - - while( idx-- ) - base[slot * keysize + idx] = test, test >>= 8; -#endif - for( idx = 0; idx < slot; idx++ ) - node[-idx-1] = node[-idx-2];// copy tree ptrs/cells down one slot - - node[-slot-1] = 0; // set new tree ptr/cell - next = &node[-slot-1]; - - if( !judy->depth && !(value & 0xFF) || judy->depth && depth == judy->depth ) { -#ifdef ASKITIS - if( *next ) - Found++; - else - Inserts++; -#endif - return next; - } - - continue; - } - - if( size < JudySize[JUDY_max] ) { - next = judy_promote (judy, next, slot+1, value, keysize); - - if( !judy->depth && !(value & 0xFF) || judy->depth && depth == judy->depth ) { -#ifdef ASKITIS - if( *next ) - Found++; - else - Inserts++; -#endif - return next; - } - - continue; - } - - // split full maximal node into JUDY_radix nodes - // loop to reprocess new insert - - judy_splitnode (judy, next, size, keysize, depth); -#ifndef ASKITIS - judy->level--; -#endif - off = start; - if( judy->depth ) - depth--; - continue; - - case JUDY_radix: - table = (JudySlot *)(*next & JUDY_mask); // outer radix - - if( judy->depth ) - slot = (src[depth] >> ((JUDY_key_size - ++off & JUDY_key_mask) * 8)) & 0xff; - else if( off < max ) - slot = buff[off++]; - else - slot = 0, off++; - - if( judy->depth ) - if( !(off & JUDY_key_mask) ) - depth++; - - // allocate inner radix if empty - - if( !table[slot >> 4] ) - table[slot >> 4] = (JudySlot)judy_alloc (judy, JUDY_radix) | JUDY_radix; - - table = (JudySlot *)(table[slot >> 4] & JUDY_mask); -#ifndef ASKITIS - judy->stack[judy->level].slot = slot; -#endif - next = &table[slot & 0x0F]; - - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) { // leaf? -#ifdef ASKITIS - if( *next ) - Found++; - else - Inserts++; -#endif - return next; - } - - continue; - -#ifndef ASKITIS - case JUDY_span: - base = (unsigned char *)(*next & JUDY_mask); - node = (JudySlot *)((*next & JUDY_mask) + JudySize[JUDY_span]); - cnt = JUDY_span_bytes; - tst = cnt; - - if( tst > (int)(max - off) ) - tst = max - off; - - value = strncmp((const char *)base, (const char *)(buff + off), tst); - - if( !value && tst < cnt && !base[tst] ) // leaf? - return &node[-1]; - - if( !value && tst == cnt ) { - next = &node[-1]; - off += cnt; - continue; - } - - // bust up JUDY_span node and produce JUDY_1 nodes - // then loop to reprocess insert - - judy_splitspan (judy, next, base); - judy->level--; - continue; -#endif - } - } - - // place JUDY_1 node under JUDY_radix node(s) - -#ifndef ASKITIS - if( off & JUDY_key_mask ) - if( judy->depth || off <= max ) { -#else - while( off <= max ) { -#endif - base = judy_alloc (judy, JUDY_1); - keysize = JUDY_key_size - (off & JUDY_key_mask); - node = (JudySlot *)(base + JudySize[JUDY_1]); - *next = (JudySlot)base | JUDY_1; - - // fill in slot 0 with bytes of key - - if( judy->depth ) { - value = src[depth]; -#if BYTE_ORDER != BIG_ENDIAN - memcpy(base, &value, keysize); // copy new key into slot -#else - while( keysize-- ) - base[keysize] = value, value >>= 8; -#endif - } else { -#if BYTE_ORDER != BIG_ENDIAN - while( keysize ) - if( off + keysize <= max ) - *base++ = buff[off + --keysize]; - else - base++, --keysize; -#else - tst = keysize; - - if( tst > (int)(max - off) ) - tst = max - off; - - memcpy (base, buff + off, tst); -#endif - } -#ifndef ASKITIS - if( judy->level < judy->max ) - judy->level++; - judy->stack[judy->level].next = *next; - judy->stack[judy->level].slot = 0; - judy->stack[judy->level].off = off; -#endif - next = &node[-1]; - - off |= JUDY_key_mask; - depth++; - off++; - } - - // produce span nodes to consume rest of key - // or judy_1 nodes if not string tree - -#ifndef ASKITIS - if( !judy->depth ) - while( off <= max ) { - base = judy_alloc (judy, JUDY_span); - *next = (JudySlot)base | JUDY_span; - node = (JudySlot *)(base + JudySize[JUDY_span]); - cnt = tst = JUDY_span_bytes; - if( tst > (int)(max - off) ) - tst = max - off; - memcpy (base, buff + off, tst); - - if( judy->level < judy->max ) - judy->level++; - judy->stack[judy->level].next = *next; - judy->stack[judy->level].slot = 0; - judy->stack[judy->level].off = off; - next = &node[-1]; - off += tst; - depth++; - - if( !base[cnt-1] ) // done on leaf - break; - } - else - while( depth < judy->depth ) { - base = judy_alloc (judy, JUDY_1); - node = (JudySlot *)(base + JudySize[JUDY_1]); - *next = (JudySlot)base | JUDY_1; - - // fill in slot 0 with bytes of key - - *(judyvalue *)base = src[depth]; - - if( judy->level < judy->max ) - judy->level++; - judy->stack[judy->level].next = *next; - judy->stack[judy->level].slot = 0; - judy->stack[judy->level].off = off; - next = &node[-1]; - off |= JUDY_key_mask; - depth++; - off++; - } -#endif - -#ifdef ASKITIS - Inserts++; -#endif - return next; -} - -#if defined(STANDALONE) || defined(ASKITIS) - -#if defined(__APPLE__) || defined(linux) -#include -#include -#include -#include -#include -#else -#include -#include -#endif - -#include - -// memory map input file and sort - -// define pennysort parameters - -unsigned int PennyRecs = (4096 * 400); // records to sort to temp files -unsigned int PennyLine = 100; // length of input record -unsigned int PennyKey = 10; // length of input key -unsigned int PennyOff = 0; // key offset in input record - -unsigned long long PennyMerge; // PennyRecs * PennyLine = file map length -unsigned int PennyPasses; // number of intermediate files created -unsigned int PennySortTime; // cpu time to run sort -unsigned int PennyMergeTime; // cpu time to run merge - -typedef struct { - void *buff; // record pointer in input file map - void *next; // duplicate chain -} PennySort; - -void sort (FILE *infile, char *outname) -{ -unsigned long long size, off, offset, part; -int ifd = fileno (infile); -char filename[512]; -PennySort *line; -JudySlot *cell; -unsigned char *inbuff; -void *judy; -FILE *out; -#if defined(_WIN32) -HANDLE hndl, fm; -DWORD hiword; -FILETIME dummy[1]; -FILETIME user[1]; -#else -struct tms buff[1]; -#endif -time_t start = time(NULL); - - if( PennyOff + PennyKey > PennyLine ) - fprintf (stderr, "Key Offset + Key Length > Record Length\n"), exit(1); - - offset = 0; - PennyPasses = 0; - -#if defined(_WIN32) - hndl = (HANDLE)_get_osfhandle(ifd); - size = GetFileSize (hndl, &hiword); - fm = CreateFileMapping(hndl, NULL, PAGE_READONLY, hiword, (DWORD)size, NULL); - if( !fm ) - fprintf (stderr, "CreateFileMapping error %d\n", GetLastError()), exit(1); - size |= (unsigned long long)hiword << 32; -#else - size = lseek (ifd, 0L, 2); -#endif - - while( offset < size ) { -#if defined(_WIN32) - part = offset + PennyMerge > size ? size - offset : PennyMerge; - inbuff = MapViewOfFile( fm, FILE_MAP_READ, offset >> 32, offset, part); - if( !inbuff ) - fprintf (stderr, "MapViewOfFile error %d\n", GetLastError()), exit(1); -#else - inbuff = mmap (NULL, PennyMerge, PROT_READ, MAP_SHARED, ifd, offset); - - if( inbuff == MAP_FAILED ) - fprintf (stderr, "mmap error %d\n", errno), exit(1); - - if( madvise (inbuff, PennyMerge, MADV_WILLNEED | MADV_SEQUENTIAL) < 0 ) - fprintf (stderr, "madvise error %d\n", errno); -#endif - judy = judy_open (PennyKey, 0); - - off = 0; - - // build judy array from mapped input chunk - - while( offset + off < size && off < PennyMerge ) { - line = judy_data (judy, sizeof(PennySort)); - cell = judy_cell (judy, inbuff + off + PennyOff, PennyKey); - line->next = *(void **)cell; - line->buff = inbuff + off; - - *(PennySort **)cell = line; - off += PennyLine; - } - - sprintf (filename, "%s.%d", outname, PennyPasses); - out = fopen (filename, "wb"); - setvbuf (out, NULL, _IOFBF, 4096 * 1024); - -#ifndef _WIN32 - if( madvise (inbuff, PennyMerge, MADV_WILLNEED | MADV_RANDOM) < 0 ) - fprintf (stderr, "madvise error %d\n", errno); -#endif - - // write judy array in sorted order to temporary file - - cell = judy_strt (judy, NULL, 0); - - if( cell ) do { - line = *(PennySort **)cell; - do fwrite (line->buff, PennyLine, 1, out); - while( line = line->next ); - } while( cell = judy_nxt (judy) ); - -#if defined(_WIN32) - UnmapViewOfFile (inbuff); -#else - munmap (inbuff, PennyMerge); -#endif - judy_close (judy); - offset += off; - fflush (out); - fclose (out); - PennyPasses++; - } - fprintf (stderr, "End Sort %d secs", time(NULL) - start); -#if defined(_WIN32) - CloseHandle (fm); - GetProcessTimes (GetCurrentProcess(), dummy, dummy, dummy, user); - PennySortTime = *(unsigned long long*)user / 10000000; -#else - times (buff); - PennySortTime = buff->tms_utime/100; -#endif - fprintf (stderr, " Cpu %d\n", PennySortTime); -} - -int merge (FILE *out, char *outname) -{ -time_t start = time(NULL); -char filename[512]; -JudySlot *cell; -unsigned int nxt, idx; -unsigned char **line; -unsigned int *next; -void *judy; -FILE **in; - - next = calloc (PennyPasses + 1, sizeof(unsigned int)); - line = calloc (PennyPasses, sizeof(void *)); - in = calloc (PennyPasses, sizeof(void *)); - - judy = judy_open (PennyKey, 0); - - // initialize merge with one record from each temp file - - for( idx = 0; idx < PennyPasses; idx++ ) { - sprintf (filename, "%s.%d", outname, idx); - in[idx] = fopen (filename, "rb"); - line[idx] = malloc (PennyLine); - setvbuf (in[idx], NULL, _IOFBF, 4096 * 1024); - fread (line[idx], PennyLine, 1, in[idx]); - cell = judy_cell (judy, line[idx] + PennyOff, PennyKey); - next[idx + 1] = *(unsigned int *)cell; - *cell = idx + 1; - } - - // output records, replacing smallest each time - - while( cell = judy_strt (judy, NULL, 0) ) { - nxt = *(unsigned int *)cell; - judy_del (judy); - - // process duplicates - - while( idx = nxt ) { - nxt = next[idx--]; - fwrite (line[idx], PennyLine, 1, out); - - if( fread (line[idx], PennyLine, 1, in[idx]) ) { - cell = judy_cell (judy, line[idx] + PennyOff, PennyKey); - next[idx + 1] = *(unsigned int *)cell; - *cell = idx + 1; - } else - next[idx + 1] = 0; - } - } - - for( idx = 0; idx < PennyPasses; idx++ ) { - fclose (in[idx]); - free (line[idx]); - } - - free (line); - free (next); - free (in); - - fprintf (stderr, "End Merge %d secs", time(NULL) - start); -#ifdef _WIN32 - { - FILETIME dummy[1]; - FILETIME user[1]; - GetProcessTimes (GetCurrentProcess(), dummy, dummy, dummy, user); - PennyMergeTime = *(unsigned long long*)user / 10000000; - } -#else - { - struct tms buff[1]; - times (buff); - PennyMergeTime = buff->tms_utime/100; - } -#endif - fprintf (stderr, " Cpu %d\n", PennyMergeTime - PennySortTime); - judy_close (judy); - fflush (out); - fclose (out); - return 0; -} - -// compilation: -// cc -O3 judy64j.c - -// usage: -// a.out [in-file] [out-file] [keysize] [recordlen] [keyoffset] [mergerecs] -// where keysize is 10 to indicate pennysort files - -#if !defined(_WIN32) -typedef struct timeval timer; -#endif - -// ASKITIS compilation: -// cc -O3 judy64n.c - -// usage: -// a.out [in-file] [out-file] [keysize] [recordlen] [keyoffset] [mergerecs] -// where keysize is 10 to indicate pennysort files - -// naskitis.com. -// g++ -O3 -fpermissive -fomit-frame-pointer -w -D STANDALONE -D ASKITIS -o judy64n judy64n.c -// ./judy64n [input-file-to-build-judy] e.g. distinct_1 or skew1_1 - -// note: the judy array is an in-memory data structure. As such, make sure you -// have enough memory to hold the entire input file + data structure, otherwise -// you'll have to break the input file into smaller pieces and load them in -// on-by-one. - -// Also, the file to search judy is hardcoded to skew1_1. - -int main (int argc, char **argv) -{ -unsigned char buff[1024]; -JudySlot max = 0; -JudySlot *cell; -FILE *in, *out; -void *judy; -unsigned int len; -unsigned int idx; -#ifdef ASKITIS -char *askitis; -int prev, off; -float insert_real_time=0.0; -float search_real_time=0.0; -int size; -#if !defined(_WIN32) -timer start, stop; -#else -time_t start[1], stop[1]; -#endif -#endif - - if( argc > 1 ) - in = fopen (argv[1], "rb"); - else - in = stdin; - - if( argc > 2 ) - out = fopen (argv[2], "wb"); - else - out = stdout; - - setvbuf (out, NULL, _IOFBF, 4096 * 1024); - - if( !in ) - fprintf (stderr, "unable to open input file\n"); - - if( !out ) - fprintf (stderr, "unable to open output file\n"); - - if( argc > 6 ) - PennyRecs = atoi(argv[6]); - - if( argc > 5 ) - PennyOff = atoi(argv[5]); - - if( argc > 4 ) - PennyLine = atoi(argv[4]); - - PennyMerge = (unsigned long long)PennyLine * PennyRecs; - - if( argc > 3 ) { - PennyKey = atoi(argv[3]); - sort (in, argv[2]); - return merge (out, argv[2]); - } - -#ifdef ASKITIS - judy = judy_open (1024, 0); - -// build judy array - size = lseek (fileno(in), 0L, 2); - askitis = malloc(size); - lseek (fileno(in), 0L, 0); - read (fileno(in), askitis,size); - prev = 0; -// naskitis.com: -// Start the timer. - -#if !defined(_WIN32) - gettimeofday(&start, NULL); -#else - time(start); -#endif - - for( off = 0; off < size; off++ ) - if( askitis[off] == '\n' ) { - *(judy_cell (judy, askitis+prev, off - prev)) += 1; // count instances of string - prev = off + 1; - } -// naskitis.com: -// Stop the timer and do some math to compute the time required to insert the strings into the judy array. - -#if !defined(_WIN32) - gettimeofday(&stop, NULL); - - insert_real_time = 1000.0 * ( stop.tv_sec - start.tv_sec ) + 0.001 * (stop.tv_usec - start.tv_usec ); - insert_real_time = insert_real_time/1000.0; -#else - time (stop); - insert_real_time = *stop - *start; -#endif - -// naskitis.com: -// Free the input buffer used to store the first file. We must do this before we get the process size below. - free (askitis); - fprintf(stderr, "JudyArray@Karl_Malbrain\nDASKITIS option enabled\n-------------------------------\n%-20s %.2f MB\n%-20s %.2f sec\n", - "Judy Array size:", MaxMem/1000000., "Time to insert:", insert_real_time); - fprintf(stderr, "%-20s %d\n", "Words:", Words); - fprintf(stderr, "%-20s %d\n", "Inserts:", Inserts); - fprintf(stderr, "%-20s %d\n", "Found:", Found); - - Words = 0; - Inserts = 0; - Found = 0; - -// search judy array - if( in = freopen ("skew1_1", "rb", in) ) - size = lseek (fileno(in), 0L, 2); - else - exit(0); - askitis = malloc(size); - lseek (fileno(in), 0L, 0); - read (fileno(in), askitis,size); - prev = 0; - -#if !defined(_WIN32) - gettimeofday(&start, NULL); -#else - time(start); -#endif - - for( off = 0; off < size; off++ ) - if( askitis[off] == '\n' ) { - *judy_cell (judy, askitis+prev, off - prev) += 1; - prev = off + 1; - } -// naskitis.com: -// Stop the timer and do some math to compute the time required to search the judy array. - -#if !defined(_WIN32) - gettimeofday(&stop, NULL); - search_real_time = 1000.0 * ( stop.tv_sec - start.tv_sec ) + 0.001 - * (stop.tv_usec - start.tv_usec ); - search_real_time = search_real_time/1000.0; -#else - time(stop); - search_real_time = *stop - *start; -#endif - -// naskitis.com: -// To do: report a count on the number of strings found. - - fprintf(stderr,"\n%-20s %.2f MB\n%-20s %.2f sec\n", - "Judy Array size:", MaxMem/1000000., "Time to search:", search_real_time); - fprintf(stderr, "%-20s %d\n", "Words:", Words); - fprintf(stderr, "%-20s %d\n", "Inserts:", Inserts); - fprintf(stderr, "%-20s %d\n", "Found:", Found); - exit(0); -#endif -#ifdef HEXKEYS - judy = judy_open (1024, 16/JUDY_key_size); - - while( fgets((char *)buff, sizeof(buff), in) ) { - judyvalue key[16/JUDY_key_size]; - if( len = strlen((const char *)buff) ) - buff[--len] = 0; // remove LF -#if JUDY_key_size == 4 - key[3] = strtoul (buff + 24, NULL, 16); - buff[24] = 0; - key[2] = strtoul (buff + 16, NULL, 16); - buff[16] = 0; - key[1] = strtoul (buff + 8, NULL, 16); - buff[8] = 0; - key[0] = strtoul (buff, NULL, 16); -#else - key[1] = strtoull (buff + 16, NULL, 16); - buff[16] = 0; - key[0] = strtoull (buff, NULL, 16); -#endif - *(judy_cell (judy, (void *)key, 0)) += 1; // count instances of string - max++; - } - - fprintf(stderr, "%" PRIuint " memory used\n", MaxMem); - - cell = judy_strt (judy, NULL, 0); - - if( cell ) do { - judyvalue key[16/JUDY_key_size]; - len = judy_key(judy, (void *)key, 0); - for( idx = 0; idx < *cell; idx++ ){ // spit out duplicates -#if JUDY_key_size == 4 - fprintf (out, "%.8X", key[0]); - fprintf (out, "%.8X", key[1]); - fprintf (out, "%.8X", key[2]); - fprintf (out, "%.8X", key[3]); -#else - fprintf (out, "%.16llX", key[0]); - fprintf (out, "%.16llX", key[1]); -#endif - fputc('\n', out); - } - } while( cell = judy_nxt (judy) ); - -#else - judy = judy_open (1024, 0); - - while( fgets((char *)buff, sizeof(buff), in) ) { - if( len = strlen((const char *)buff) ) - buff[--len] = 0; // remove LF - *(judy_cell (judy, buff, len)) += 1; // count instances of string - max++; - } - - fprintf(stderr, "%" PRIuint " memory used\n", MaxMem); - - cell = judy_strt (judy, NULL, 0); - - if( cell ) do { - len = judy_key(judy, buff, sizeof(buff)); - for( idx = 0; idx < *cell; idx++ ){ // spit out duplicates - fwrite(buff, len, 1, out); - fputc('\n', out); - } - } while( cell = judy_nxt (judy) ); -#endif -#if 0 - // test deletion all the way to an empty tree - - if( cell = judy_prv (judy) ) - do max -= *cell; - while( cell = judy_del (judy) ); - - assert (max == 0); -#endif - judy_close(judy); - return 0; -} -#endif - diff --git a/src/base/judy/test/hexSort.c b/src/base/judy/test/hexSort.c deleted file mode 100644 index 0d770d752..000000000 --- a/src/base/judy/test/hexSort.c +++ /dev/null @@ -1,124 +0,0 @@ -// Judy arrays 13 DEC 2012 (judy64n.c from http://code.google.com/p/judyarray/ ) -// This code is public domain. - -// Author Karl Malbrain, malbrain AT yahoo.com -// with assistance from Jan Weiss. -// modifications (and any bugs) by Mark Pictor, mpictor at gmail - -// Simplified judy arrays for strings and integers -// Adapted from the ideas of Douglas Baskins of HP. - -// Map a set of keys to corresponding memory cells (uints). -// Each cell must be set to a non-zero value by the caller. - - -// Integer mappings are denoted by calling judy_open with the -// Integer depth of the Judy Trie as the second argument. - -#ifndef STANDALONE -# error must define STANDALONE while compiling this file and judy64.c -#endif - -#include "judy.h" -#include "sort.h" - -unsigned int MaxMem = 0; -/** - usage: - a.out [in-file] [out-file] - where all lines of in-file are 32 chars, hexadecimal - On linux, a 1M-line file can be created with the following: - hexdump -v -e '2/8 "%08x"' -e '"\n"' /dev/urandom |head -n 1000000 >in-file -*/ -int main( int argc, char ** argv ) { - unsigned char buff[1024]; - JudySlot max = 0; - JudySlot * cell; - FILE * in, *out; - void * judy; - unsigned int len; - unsigned int idx; - - if( argc > 1 ) { - in = fopen( argv[1], "rb" ); - } else { - in = stdin; - } - - if( argc > 2 ) { - out = fopen( argv[2], "wb" ); - } else { - out = stdout; - } - - setvbuf( out, NULL, _IOFBF, 4096 * 1024 ); - - if( !in ) { - fprintf( stderr, "unable to open input file\n" ); - } - - if( !out ) { - fprintf( stderr, "unable to open output file\n" ); - } - - PennyMerge = ( unsigned long long )PennyLine * PennyRecs; - - judy = judy_open( 1024, 16 / JUDY_key_size ); - - while( fgets( ( char * )buff, sizeof( buff ), in ) ) { - judyvalue key[16 / JUDY_key_size]; - if( len = strlen( ( const char * )buff ) ) { - buff[--len] = 0; // remove LF - } -#if JUDY_key_size == 4 - key[3] = strtoul( buff + 24, NULL, 16 ); - buff[24] = 0; - key[2] = strtoul( buff + 16, NULL, 16 ); - buff[16] = 0; - key[1] = strtoul( buff + 8, NULL, 16 ); - buff[8] = 0; - key[0] = strtoul( buff, NULL, 16 ); -#else - key[1] = strtoull( buff + 16, NULL, 16 ); - buff[16] = 0; - key[0] = strtoull( buff, NULL, 16 ); -#endif - *( judy_cell( judy, ( void * )key, 0 ) ) += 1; // count instances of string - max++; - } - - fprintf( stderr, "%" PRIuint " memory used\n", MaxMem ); - - cell = judy_strt( judy, NULL, 0 ); - - if( cell ) do { - judyvalue key[16 / JUDY_key_size]; - len = judy_key( judy, ( void * )key, 0 ); - for( idx = 0; idx < *cell; idx++ ) { // spit out duplicates -#if JUDY_key_size == 4 - fprintf( out, "%.8X", key[0] ); - fprintf( out, "%.8X", key[1] ); - fprintf( out, "%.8X", key[2] ); - fprintf( out, "%.8X", key[3] ); -#else - fprintf( out, "%.16llX", key[0] ); - fprintf( out, "%.16llX", key[1] ); -#endif - fputc( '\n', out ); - } - } while( cell = judy_nxt( judy ) ); - -#if 0 - // test deletion all the way to an empty tree - - if( cell = judy_prv( judy ) ) - do { - max -= *cell; - } while( cell = judy_del( judy ) ); - - assert( max == 0 ); -#endif - judy_close( judy ); - return 0; -} - diff --git a/src/base/judy/test/judyL2test.cc b/src/base/judy/test/judyL2test.cc deleted file mode 100644 index 20ef559a9..000000000 --- a/src/base/judy/test/judyL2test.cc +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include -#include - -#include "judyL2Array.h" -typedef judyL2Array< uint64_t, uint64_t > jl2a; - -bool testFind( jl2a & j, uint64_t key, unsigned int count ) { - jl2a::cvector * v = j.find( key ); - std::cout << "find: key " << key << " ..." << std::endl; - if( count > 0 ) { - if( !v || !j.success() || ( v->size() != count ) ) { - std::cout << " false negative - v: " << v << " success: " << j.success(); - if( v ) { - std::cout << " expected count: " << count << " actual: " << v->size(); - } - std::cout << std::endl; - return false; - } else { - // note - this doesn't verify that the right keys are returned, just the right number! - jl2a::vector::const_iterator it = v->begin(); - std::cout << " correct number of values -"; - for( ; it != v->end(); it++ ) { - std::cout << " " << *it; - } - std::cout << std::endl; - } - } else { - if( v || j.success() ) { - std::cout << " false positive - v: " << v << " success: " << j.success() << std::endl; - return false; - } else { - std::cout << " not found, as expected." << std::endl; - } - } - return true; -} - -int main() { - bool pass = true; - jl2a jl; - std::cout.setf( std::ios::boolalpha ); -// std::cout << "size of judyL2Array: " << sizeof( jl ) << std::endl; - jl.insert( 5, 12 ); - jl.insert( 6, 2 ); - jl.insert( 7, 312 ); - jl.insert( 11, 412 ); - jl.insert( 7, 313 ); - jl2a::cpair kv = jl.atOrAfter( 4 ); - std::cout << "atOrAfter test ..." << std::endl; - if( kv.value != 0 && jl.success() ) { - std::cout << " key " << kv.key << " value " << kv.value->at( 0 ) << std::endl; - } else { - std::cout << " failed" << std::endl; - pass = false; - } - - pass &= testFind( jl, 8, 0 ); - pass &= testFind( jl, 11, 1 ); - pass &= testFind( jl, 7, 2 ); - - jl.clear(); - - //TODO test all of judyL2Array - if( pass ) { - std::cout << "All tests passed." << std::endl; - exit( EXIT_SUCCESS ); - } else { - std::cout << "At least one test failed." << std::endl; - exit( EXIT_FAILURE ); - } -} \ No newline at end of file diff --git a/src/base/judy/test/judyLtest.cc b/src/base/judy/test/judyLtest.cc deleted file mode 100644 index 01ae3d5d7..000000000 --- a/src/base/judy/test/judyLtest.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include -#include - -#include "judyLArray.h" - -int main() { - std::cout.setf( std::ios::boolalpha ); - judyLArray< uint64_t, uint64_t > jl; - std::cout << "size of judyLArray: " << sizeof( jl ) << std::endl; - jl.insert( 5, 12 ); - jl.insert( 6, 2 ); - jl.insert( 7, 312 ); - jl.insert( 8, 412 ); - judyLArray< uint64_t, uint64_t >::pair kv = jl.atOrAfter( 4 ); - std::cout << "k " << kv.key << " v " << kv.value << std::endl; - - long v = jl.find( 11 ); - if( v != 0 || jl.success() ) { - std::cout << "find: false positive - v: " << v << " success: " << jl.success() << std::endl; - exit( EXIT_FAILURE ); - } - v = jl.find( 7 ); - if( v != 312 || !jl.success() ) { - std::cout << "find: false negative - v: " << v << " success: " << jl.success() << std::endl; - exit( EXIT_FAILURE ); - } - - jl.clear(); - - //TODO test all of judyLArray - exit( EXIT_SUCCESS ); -} \ No newline at end of file diff --git a/src/base/judy/test/judyS2test.cc b/src/base/judy/test/judyS2test.cc deleted file mode 100644 index ec25f960b..000000000 --- a/src/base/judy/test/judyS2test.cc +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include - -#include "judyS2Array.h" - -typedef judyS2Array< uint64_t > js2a; - -bool testFind( js2a & j, const char * key, unsigned int count ) { - js2a::cvector * v = j.find( key ); - std::cout << "find: key " << key << " ..." << std::endl; - if( count > 0 ) { - if( !v || !j.success() || ( v->size() != count ) ) { - std::cout << " false negative - v: " << v << " success: " << j.success(); - if( v ) { - std::cout << " expected count: " << count << " actual: " << v->size(); - } - std::cout << std::endl; - return false; - } else { - // note - this doesn't verify that the right keys are returned, just the right number! - js2a::vector::const_iterator it = v->begin(); - std::cout << " correct number of values -"; - for( ; it != v->end(); it++ ) { - std::cout << " " << *it; - } - std::cout << std::endl; - } - } else { - if( v || j.success() ) { - std::cout << " false positive - v: " << v << " success: " << j.success() << std::endl; - return false; - } else { - std::cout << " not found, as expected." << std::endl; - } - } - return true; -} - -int main() { - bool pass = true; - std::cout.setf( std::ios::boolalpha ); - - js2a js( 255 ); - js.insert( "blah", 1234 ); - js.insert( "bah", 124 ); - js.insert( "blh", 123 ); - js.insert( "blh", 4123 ); - js.insert( "bla", 134 ); - js.insert( "bh", 234 ); - - js2a::cpair kv = js.atOrAfter( "ab" ); - std::cout << "atOrAfter test ..." << std::endl; - if( kv.value != 0 && js.success() ) { - std::cout << " key " << kv.key << " value " << kv.value->at( 0 ) << std::endl; - } else { - std::cout << " failed" << std::endl; - pass = false; - } - - pass &= testFind( js, "sdafsd", 0 ); - pass &= testFind( js, "bah", 1 ); - pass &= testFind( js, "blh", 2 ); - - js.clear(); - - //TODO test all of judyS2Array - if( pass ) { - std::cout << "All tests passed." << std::endl; - exit( EXIT_SUCCESS ); - } else { - std::cout << "At least one test failed." << std::endl; - exit( EXIT_FAILURE ); - } -} \ No newline at end of file diff --git a/src/base/judy/test/judyStest.cc b/src/base/judy/test/judyStest.cc deleted file mode 100644 index 3d620b015..000000000 --- a/src/base/judy/test/judyStest.cc +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -#include "judySArray.h" - -int main() { - bool pass = true; - std::cout.setf( std::ios::boolalpha ); - - judySArray< uint64_t > js( 255 ); - js.insert( "blah", 1234 ); - js.insert( "bah", 124 ); - js.insert( "blh", 123 ); - js.insert( "bla", 134 ); - js.insert( "bh", 234 ); - - - judySArray< uint64_t >::pair kv = js.atOrAfter( "ab" ); - //TODO if()... - std::cout << "k " << kv.key << " v " << kv.value << std::endl; - - long v = js.find( "sdafsd" ); - if( v != 0 || js.success() ) { - std::cout << "find: false positive - v: " << v << " success: " << js.success() << std::endl; - pass = false; - } - v = js.find( "bah" ); - if( v != 124 || !js.success() ) { - std::cout << "find: false negative - v: " << v << " success: " << js.success() << std::endl; - pass = false; - } - - - //TODO test all of judySArray - if( pass ) { - std::cout << "All tests passed." << std::endl; - exit( EXIT_SUCCESS ); - } else { - std::cout << "At least one test failed." << std::endl; - exit( EXIT_FAILURE ); - } -} \ No newline at end of file diff --git a/src/base/judy/test/pennySort.c b/src/base/judy/test/pennySort.c deleted file mode 100644 index a279b1a70..000000000 --- a/src/base/judy/test/pennySort.c +++ /dev/null @@ -1,236 +0,0 @@ -// Judy arrays 13 DEC 2012 (judy64n.c from http://code.google.com/p/judyarray/ ) -// This code is public domain. - -// Author Karl Malbrain, malbrain AT yahoo.com -// with assistance from Jan Weiss. -// modifications (and any bugs) by Mark Pictor, mpictor at gmail - -// Simplified judy arrays for strings and integers -// Adapted from the ideas of Douglas Baskins of HP. - -// Map a set of keys to corresponding memory cells (uints). -// Each cell must be set to a non-zero value by the caller. - -// STANDALONE is defined to compile into a string sorter. - -// String mappings are denoted by calling judy_open with zero as -// the second argument. - -#ifndef STANDALONE -# error must define STANDALONE while compiling this file and judy64.c -#endif - -#include "judy.h" -#include "sort.h" - -unsigned int MaxMem = 0; - -// usage: -// a.out [in-file] [out-file] [keysize] [recordlen] [keyoffset] [mergerecs] -// where keysize is 10 to indicate pennysort files - -// ASKITIS compilation: -// g++ -O3 -fpermissive -fomit-frame-pointer -w -D STANDALONE -D ASKITIS -o judy64n judy64n.c -// ./judy64n [input-file-to-build-judy] e.g. distinct_1 or skew1_1 - -// note: the judy array is an in-memory data structure. As such, make sure you -// have enough memory to hold the entire input file + data structure, otherwise -// you'll have to break the input file into smaller pieces and load them in -// on-by-one. - -// Also, the file to search judy is hardcoded to skew1_1. - -int main( int argc, char ** argv ) { - unsigned char buff[1024]; - JudySlot max = 0; - JudySlot * cell; - FILE * in, *out; - void * judy; - unsigned int len; - unsigned int idx; -#ifdef ASKITIS - char * askitis; - int prev, off; - float insert_real_time = 0.0; - float search_real_time = 0.0; - int size; -#if !defined(_WIN32) - timer start, stop; -#else - time_t start[1], stop[1]; -#endif -#endif - - if( argc > 1 ) { - in = fopen( argv[1], "rb" ); - } else { - in = stdin; - } - - if( argc > 2 ) { - out = fopen( argv[2], "wb" ); - } else { - out = stdout; - } - - setvbuf( out, NULL, _IOFBF, 4096 * 1024 ); - - if( !in ) { - fprintf( stderr, "unable to open input file\n" ); - } - - if( !out ) { - fprintf( stderr, "unable to open output file\n" ); - } - - if( argc > 6 ) { - PennyRecs = atoi( argv[6] ); - } - - if( argc > 5 ) { - PennyOff = atoi( argv[5] ); - } - - if( argc > 4 ) { - PennyLine = atoi( argv[4] ); - } - - PennyMerge = ( unsigned long long )PennyLine * PennyRecs; - - if( argc > 3 ) { - PennyKey = atoi( argv[3] ); - sort( in, argv[2] ); - return merge( out, argv[2] ); - } - -#ifdef ASKITIS - judy = judy_open( 1024, 0 ); - -// build judy array - size = lseek( fileno( in ), 0L, 2 ); - askitis = malloc( size ); - lseek( fileno( in ), 0L, 0 ); - read( fileno( in ), askitis, size ); - prev = 0; -// naskitis.com: -// Start the timer. - -#if !defined(_WIN32) - gettimeofday( &start, NULL ); -#else - time( start ); -#endif - - for( off = 0; off < size; off++ ) - if( askitis[off] == '\n' ) { - *( judy_cell( judy, askitis + prev, off - prev ) ) += 1; // count instances of string - prev = off + 1; - } -// naskitis.com: -// Stop the timer and do some math to compute the time required to insert the strings into the judy array. - -#if !defined(_WIN32) - gettimeofday( &stop, NULL ); - - insert_real_time = 1000.0 * ( stop.tv_sec - start.tv_sec ) + 0.001 * ( stop.tv_usec - start.tv_usec ); - insert_real_time = insert_real_time / 1000.0; -#else - time( stop ); - insert_real_time = *stop - *start; -#endif - -// naskitis.com: -// Free the input buffer used to store the first file. We must do this before we get the process size below. - free( askitis ); - fprintf( stderr, "JudyArray@Karl_Malbrain\nDASKITIS option enabled\n-------------------------------\n%-20s %.2f MB\n%-20s %.2f sec\n", - "Judy Array size:", MaxMem / 1000000., "Time to insert:", insert_real_time ); - fprintf( stderr, "%-20s %d\n", "Words:", Words ); - fprintf( stderr, "%-20s %d\n", "Inserts:", Inserts ); - fprintf( stderr, "%-20s %d\n", "Found:", Found ); - - Words = 0; - Inserts = 0; - Found = 0; - -// search judy array - if( in = freopen( "skew1_1", "rb", in ) ) { - size = lseek( fileno( in ), 0L, 2 ); - } else { - exit( 0 ); - } - askitis = malloc( size ); - lseek( fileno( in ), 0L, 0 ); - read( fileno( in ), askitis, size ); - prev = 0; - -#if !defined(_WIN32) - gettimeofday( &start, NULL ); -#else - time( start ); -#endif - - for( off = 0; off < size; off++ ) - if( askitis[off] == '\n' ) { - *judy_cell( judy, askitis + prev, off - prev ) += 1; - prev = off + 1; - } -// naskitis.com: -// Stop the timer and do some math to compute the time required to search the judy array. - -#if !defined(_WIN32) - gettimeofday( &stop, NULL ); - search_real_time = 1000.0 * ( stop.tv_sec - start.tv_sec ) + 0.001 - * ( stop.tv_usec - start.tv_usec ); - search_real_time = search_real_time / 1000.0; -#else - time( stop ); - search_real_time = *stop - *start; -#endif - -// naskitis.com: -// To do: report a count on the number of strings found. - - fprintf( stderr, "\n%-20s %.2f MB\n%-20s %.2f sec\n", - "Judy Array size:", MaxMem / 1000000., "Time to search:", search_real_time ); - fprintf( stderr, "%-20s %d\n", "Words:", Words ); - fprintf( stderr, "%-20s %d\n", "Inserts:", Inserts ); - fprintf( stderr, "%-20s %d\n", "Found:", Found ); - exit( 0 ); -#endif - - judy = judy_open( 1024, 0 ); - - while( fgets( ( char * )buff, sizeof( buff ), in ) ) { - if( len = strlen( ( const char * )buff ) ) { - buff[--len] = 0; // remove LF - } - *( judy_cell( judy, buff, len ) ) += 1; // count instances of string - max++; - } - - fprintf( stderr, "%" PRIuint " memory used\n", MaxMem ); - - cell = judy_strt( judy, NULL, 0 ); - - if( cell ) do { - len = judy_key( judy, buff, sizeof( buff ) ); - for( idx = 0; idx < *cell; idx++ ) { // spit out duplicates - fwrite( buff, len, 1, out ); - fputc( '\n', out ); - } - } while( cell = judy_nxt( judy ) ); - -#if 0 - // test deletion all the way to an empty tree - - if( cell = judy_prv( judy ) ) - do { - max -= *cell; - } while( cell = judy_del( judy ) ); - - assert( max == 0 ); -#endif - judy_close( judy ); - return 0; -} - diff --git a/src/base/judy/test/sort.c b/src/base/judy/test/sort.c deleted file mode 100644 index e483b92e0..000000000 --- a/src/base/judy/test/sort.c +++ /dev/null @@ -1,233 +0,0 @@ -// Judy arrays 13 DEC 2012 (judy64n.c from http://code.google.com/p/judyarray/ ) -// This code is public domain. - -// Author Karl Malbrain, malbrain AT yahoo.com -// with assistance from Jan Weiss. -// modifications (and any bugs) by Mark Pictor, mpictor at gmail - -// Simplified judy arrays for strings and integers -// Adapted from the ideas of Douglas Baskins of HP. - -// Map a set of keys to corresponding memory cells (uints). -// Each cell must be set to a non-zero value by the caller. - -// STANDALONE is defined to compile into a string sorter. - -// String mappings are denoted by calling judy_open with zero as -// the second argument. Integer mappings are denoted by calling -// judy_open with the Integer depth of the Judy Trie as the second -// argument. - -#include "judy.h" -#include "sort.h" - -// memory map input file and sort - -// define pennysort parameters -unsigned int PennyRecs = ( 4096 * 400 ); // records to sort to temp files -unsigned int PennyLine = 100; // length of input record -unsigned int PennyKey = 10; // length of input key -unsigned int PennyOff = 0; // key offset in input record - -unsigned long long PennyMerge; // PennyRecs * PennyLine = file map length -unsigned int PennyPasses; // number of intermediate files created -unsigned int PennySortTime; // cpu time to run sort -unsigned int PennyMergeTime; // cpu time to run merge - -void sort( FILE * infile, char * outname ) { - unsigned long long size, off, offset, part; - int ifd = fileno( infile ); - char filename[512]; - PennySort * line; - JudySlot * cell; - unsigned char * inbuff; - void * judy; - FILE * out; -#if defined(_WIN32) - HANDLE hndl, fm; - DWORD hiword; - FILETIME dummy[1]; - FILETIME user[1]; -#else - struct tms buff[1]; -#endif - time_t start = time( NULL ); - - if( PennyOff + PennyKey > PennyLine ) { - fprintf( stderr, "Key Offset + Key Length > Record Length\n" ), exit( 1 ); - } - - offset = 0; - PennyPasses = 0; - -#if defined(_WIN32) - hndl = ( HANDLE )_get_osfhandle( ifd ); - size = GetFileSize( hndl, &hiword ); - fm = CreateFileMapping( hndl, NULL, PAGE_READONLY, hiword, ( DWORD )size, NULL ); - if( !fm ) { - fprintf( stderr, "CreateFileMapping error %d\n", GetLastError() ), exit( 1 ); - } - size |= ( unsigned long long )hiword << 32; -#else - size = lseek( ifd, 0L, 2 ); -#endif - - while( offset < size ) { -#if defined(_WIN32) - part = offset + PennyMerge > size ? size - offset : PennyMerge; - inbuff = MapViewOfFile( fm, FILE_MAP_READ, offset >> 32, offset, part ); - if( !inbuff ) { - fprintf( stderr, "MapViewOfFile error %d\n", GetLastError() ), exit( 1 ); - } -#else - inbuff = mmap( NULL, PennyMerge, PROT_READ, MAP_SHARED, ifd, offset ); - - if( inbuff == MAP_FAILED ) { - fprintf( stderr, "mmap error %d\n", errno ), exit( 1 ); - } - - if( madvise( inbuff, PennyMerge, MADV_WILLNEED | MADV_SEQUENTIAL ) < 0 ) { - fprintf( stderr, "madvise error %d\n", errno ); - } -#endif - judy = judy_open( PennyKey, 0 ); - - off = 0; - - // build judy array from mapped input chunk - - while( offset + off < size && off < PennyMerge ) { - line = judy_data( judy, sizeof( PennySort ) ); - cell = judy_cell( judy, inbuff + off + PennyOff, PennyKey ); - line->next = *( void ** )cell; - line->buff = inbuff + off; - - *( PennySort ** )cell = line; - off += PennyLine; - } - - sprintf( filename, "%s.%d", outname, PennyPasses ); - out = fopen( filename, "wb" ); - setvbuf( out, NULL, _IOFBF, 4096 * 1024 ); - -#ifndef _WIN32 - if( madvise( inbuff, PennyMerge, MADV_WILLNEED | MADV_RANDOM ) < 0 ) { - fprintf( stderr, "madvise error %d\n", errno ); - } -#endif - - // write judy array in sorted order to temporary file - - cell = judy_strt( judy, NULL, 0 ); - - if( cell ) do { - line = *( PennySort ** )cell; - do { - fwrite( line->buff, PennyLine, 1, out ); - } while( line = line->next ); - } while( cell = judy_nxt( judy ) ); - -#if defined(_WIN32) - UnmapViewOfFile( inbuff ); -#else - munmap( inbuff, PennyMerge ); -#endif - judy_close( judy ); - offset += off; - fflush( out ); - fclose( out ); - PennyPasses++; - } - fprintf( stderr, "End Sort %llu secs", ( unsigned long long ) time( NULL ) - start ); -#if defined(_WIN32) - CloseHandle( fm ); - GetProcessTimes( GetCurrentProcess(), dummy, dummy, dummy, user ); - PennySortTime = *( unsigned long long * )user / 10000000; -#else - times( buff ); - PennySortTime = buff->tms_utime / 100; -#endif - fprintf( stderr, " Cpu %d\n", PennySortTime ); -} - -int merge( FILE * out, char * outname ) { - time_t start = time( NULL ); - char filename[512]; - JudySlot * cell; - unsigned int nxt, idx; - unsigned char ** line; - unsigned int * next; - void * judy; - FILE ** in; - - next = calloc( PennyPasses + 1, sizeof( unsigned int ) ); - line = calloc( PennyPasses, sizeof( void * ) ); - in = calloc( PennyPasses, sizeof( void * ) ); - - judy = judy_open( PennyKey, 0 ); - - // initialize merge with one record from each temp file - - for( idx = 0; idx < PennyPasses; idx++ ) { - sprintf( filename, "%s.%d", outname, idx ); - in[idx] = fopen( filename, "rb" ); - line[idx] = malloc( PennyLine ); - setvbuf( in[idx], NULL, _IOFBF, 4096 * 1024 ); - fread( line[idx], PennyLine, 1, in[idx] ); - cell = judy_cell( judy, line[idx] + PennyOff, PennyKey ); - next[idx + 1] = *( unsigned int * )cell; - *cell = idx + 1; - } - - // output records, replacing smallest each time - - while( cell = judy_strt( judy, NULL, 0 ) ) { - nxt = *( unsigned int * )cell; - judy_del( judy ); - - // process duplicates - - while( idx = nxt ) { - nxt = next[idx--]; - fwrite( line[idx], PennyLine, 1, out ); - - if( fread( line[idx], PennyLine, 1, in[idx] ) ) { - cell = judy_cell( judy, line[idx] + PennyOff, PennyKey ); - next[idx + 1] = *( unsigned int * )cell; - *cell = idx + 1; - } else { - next[idx + 1] = 0; - } - } - } - - for( idx = 0; idx < PennyPasses; idx++ ) { - fclose( in[idx] ); - free( line[idx] ); - } - - free( line ); - free( next ); - free( in ); - - fprintf( stderr, "End Merge %llu secs", ( unsigned long long ) time( NULL ) - start ); -#ifdef _WIN32 - { - FILETIME dummy[1]; - FILETIME user[1]; - GetProcessTimes( GetCurrentProcess(), dummy, dummy, dummy, user ); - PennyMergeTime = *( unsigned long long * )user / 10000000; - } -#else - { - struct tms buff[1]; - times( buff ); - PennyMergeTime = buff->tms_utime / 100; - } -#endif - fprintf( stderr, " Cpu %d\n", PennyMergeTime - PennySortTime ); - judy_close( judy ); - fflush( out ); - fclose( out ); - return 0; -} diff --git a/src/base/judy/test/sort.h b/src/base/judy/test/sort.h deleted file mode 100644 index 785e58d69..000000000 --- a/src/base/judy/test/sort.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef SORT_H -#define SORT_H - -// Judy arrays 13 DEC 2012 (judy64n.c from http://code.google.com/p/judyarray/ ) -// This code is public domain. - -// Author Karl Malbrain, malbrain AT yahoo.com -// with assistance from Jan Weiss. -// modifications (and any bugs) by Mark Pictor, mpictor at gmail - -// Simplified judy arrays for strings and integers -// Adapted from the ideas of Douglas Baskins of HP. - -// Map a set of keys to corresponding memory cells (uints). -// Each cell must be set to a non-zero value by the caller. - -// STANDALONE is defined to compile into a string sorter. - -// String mappings are denoted by calling judy_open with zero as -// the second argument. Integer mappings are denoted by calling -// judy_open with the Integer depth of the Judy Trie as the second -// argument. - -#include -#include -#include -#include -#include "judy.h" - -#ifdef linux -# include -# include -# include -# include -# include -#else -# include -# include -#endif - -#include - -#define PRIuint "u" - - -//these are initialized in penny.c -extern unsigned int PennyRecs; -extern unsigned int PennyLine; -extern unsigned int PennyKey; -extern unsigned int PennyOff; -extern unsigned long long PennyMerge; - -typedef struct { - void * buff; // record pointer in input file map - void * next; // duplicate chain -} PennySort; - -#endif //SORT_H \ No newline at end of file diff --git a/src/base/path2str.c b/src/base/path2str.c deleted file mode 100644 index 6f5aedd7c..000000000 --- a/src/base/path2str.c +++ /dev/null @@ -1,29 +0,0 @@ - -#include "path2str.h" -#include "sc_memmgr.h" -#include - -/* for windows, rewrite backslashes in paths - * that will be written to generated code - */ -const char * path2str_fn( const char * fileMacro ) { - static char * result = 0; - static size_t rlen = 0; - char * p; - if( rlen < strlen( fileMacro ) ) { - if( result ) { - sc_free( result ); - } - rlen = strlen( fileMacro ); - result = ( char * )sc_malloc( rlen * sizeof( char ) + 1 ); - } - strcpy( result, fileMacro ); - p = result; - while( *p ) { - if( *p == '\\' ) { - *p = '/'; - } - p++; - } - return result; -} diff --git a/src/base/path2str.h b/src/base/path2str.h deleted file mode 100644 index 05c2f7b91..000000000 --- a/src/base/path2str.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PATH2STR_H -#define PATH2STR_H - -#include - -/** windows only: rewrite backslashes in paths as forward slashes - * call as path2str(__FILE__) to take advantage of macro - * - * silence "unknown escape sequence" warning when contents of __FILE__ - * are fprintf'd into string in generated code - */ -SC_BASE_EXPORT const char * path2str_fn( const char * fileMacro ); - -#if defined( _WIN32 ) || defined ( __WIN32__ ) -# define path2str(path) path2str_fn(path) -#else -# define path2str(path) path -#endif /* defined( _WIN32 ) || defined ( __WIN32__ ) */ - -#endif /* PATH2STR_H */ diff --git a/src/base/sc_getopt.cc b/src/base/sc_getopt.cc deleted file mode 100644 index 01e925b56..000000000 --- a/src/base/sc_getopt.cc +++ /dev/null @@ -1,214 +0,0 @@ -/****** RENAMED from xgetopt.cc to sc_getopt.cc ***********/ - -// XGetopt.cpp Version 1.2 -// -// Author: Hans Dietrich -// hdietrich2@hotmail.com -// -// Description: -// XGetopt.cpp implements sc_getopt(), a function to parse command lines. -// -// History -// Version 1.2 - 2003 May 17 -// - Added Unicode support -// -// Version 1.1 - 2002 March 10 -// - Added example to XGetopt.cpp module header -// -// This software is released into the public domain. -// You are free to use it in any way you like. -// -// This software is provided "as is" with no expressed -// or implied warranty. I accept no liability for any -// damage or loss of business that this software may cause. -// -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// if you are using precompiled headers then include this line: -//#include "stdafx.h" -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// if you are not using precompiled headers then include these lines: -//#include -#include -#include -/////////////////////////////////////////////////////////////////////////////// - -#include "sc_getopt.h" - -/////////////////////////////////////////////////////////////////////////////// -// -// X G e t o p t . c p p -// -// -// NAME -// sc_getopt -- parse command line options -// -// SYNOPSIS -// int sc_getopt(int argc, char *argv[], char *optstring) -// -// extern char *sc_optarg; -// extern int sc_optind; -// -// DESCRIPTION -// The sc_getopt() function parses the command line arguments. Its -// arguments argc and argv are the argument count and array as -// passed into the application on program invocation. In the case -// of Visual C++ programs, argc and argv are available via the -// variables __argc and __argv (double underscores), respectively. -// sc_getopt returns the next option letter in argv that matches a -// letter in optstring. (Note: Unicode programs should use -// __targv instead of __argv. Also, all character and string -// literals should be enclosed in _T( ) ). -// -// optstring is a string of recognized option letters; if a letter -// is followed by a colon, the option is expected to have an argument -// that may or may not be separated from it by white space. sc_optarg -// is set to point to the start of the option argument on return from -// sc_getopt. -// -// Option letters may be combined, e.g., "-ab" is equivalent to -// "-a -b". Option letters are case sensitive. -// -// sc_getopt places in the external variable sc_optind the argv index -// of the next argument to be processed. sc_optind is initialized -// to 0 before the first call to sc_getopt. -// -// When all options have been processed (i.e., up to the first -// non-option argument), sc_getopt returns EOF, sc_optarg will point -// to the argument, and sc_optind will be set to the argv index of -// the argument. If there are no non-option arguments, sc_optarg -// will be set to NULL. -// -// The special option "--" may be used to delimit the end of the -// options; EOF will be returned, and "--" (and everything after it) -// will be skipped. -// -// RETURN VALUE -// For option letters contained in the string optstring, sc_getopt -// will return the option letter. sc_getopt returns a question mark (?) -// when it encounters an option letter not included in optstring. -// EOF is returned when processing is finished. -// -// BUGS -// 1) Long options are not supported. -// 2) The GNU double-colon extension is not supported. -// 3) The environment variable POSIXLY_CORRECT is not supported. -// 4) The + syntax is not supported. -// 5) The automatic permutation of arguments is not supported. -// 6) This implementation of sc_getopt() returns EOF if an error is -// encountered, instead of -1 as the latest standard requires. -// -// EXAMPLE -// BOOL CMyApp::ProcessCommandLine(int argc, char *argv[]) -// { -// int c; -// -// while ((c = sc_getopt(argc, argv, _T("aBn:"))) != EOF) -// { -// switch (c) -// { -// case _T('a'): -// TRACE(_T("option a\n")); -// // -// // set some flag here -// // -// break; -// -// case _T('B'): -// TRACE( _T("option B\n")); -// // -// // set some other flag here -// // -// break; -// -// case _T('n'): -// TRACE(_T("option n: value=%d\n"), atoi(sc_optarg)); -// // -// // do something with value here -// // -// break; -// -// case _T('?'): -// TRACE(_T("ERROR: illegal option %s\n"), argv[sc_optind-1]); -// return FALSE; -// break; -// -// default: -// TRACE(_T("WARNING: no handler for option %c\n"), c); -// return FALSE; -// break; -// } -// } -// // -// // check for non-option args here -// // -// return TRUE; -// } -// -/////////////////////////////////////////////////////////////////////////////// - -char * sc_optarg; // global argument pointer -int sc_optind = 0; // global argv index - -int sc_getopt( int argc, char * argv[], char * optstring ) { - static char * next = NULL; - if( sc_optind == 0 ) { - next = NULL; - } - - sc_optarg = NULL; - - if( next == NULL || *next == '\0' ) { - if( sc_optind == 0 ) { - sc_optind++; - } - - if( sc_optind >= argc || argv[sc_optind][0] != '-' || argv[sc_optind][1] == '\0' ) { - sc_optarg = NULL; - if( sc_optind < argc ) { - sc_optarg = argv[sc_optind]; - } - return EOF; - } - - if( strcmp( argv[sc_optind], "--" ) == 0 ) { - sc_optind++; - sc_optarg = NULL; - if( sc_optind < argc ) { - sc_optarg = argv[sc_optind]; - } - return EOF; - } - - next = argv[sc_optind]; - next++; // skip past - - sc_optind++; - } - - char c = *next++; - char * cp = strchr( optstring, c ); - - if( cp == NULL || c == ':' ) { - return '?'; - } - - cp++; - if( *cp == ':' ) { - if( *next != '\0' ) { - sc_optarg = next; - next = NULL; - } else if( sc_optind < argc ) { - sc_optarg = argv[sc_optind]; - sc_optind++; - } else { - return '?'; - } - } - - return c; -} diff --git a/src/base/sc_getopt.h b/src/base/sc_getopt.h deleted file mode 100644 index e1421a7bf..000000000 --- a/src/base/sc_getopt.h +++ /dev/null @@ -1,32 +0,0 @@ -/** \file sc_getopt.h - * this was xgetopt.h - * XGetopt.h Version 1.2 - * - * Author: Hans Dietrich - * hdietrich2@hotmail.com - * - * This software is released into the public domain. - * You are free to use it in any way you like. - * - * This software is provided "as is" with no expressed - * or implied warranty. I accept no liability for any - * damage or loss of business that this software may cause. - */ -#ifndef XGETOPT_H -#define XGETOPT_H -#include "sc_export.h" - -#ifdef __cplusplus -extern "C" { -#endif - - extern SC_BASE_EXPORT int sc_optind, sc_opterr; - extern SC_BASE_EXPORT char * sc_optarg; - - int SC_BASE_EXPORT sc_getopt( int argc, char * argv[], char * optstring ); - -#ifdef __cplusplus -} -#endif - -#endif /* XGETOPT_H */ diff --git a/src/base/sc_memmgr.cc b/src/base/sc_memmgr.cc deleted file mode 100644 index 262d26e28..000000000 --- a/src/base/sc_memmgr.cc +++ /dev/null @@ -1,405 +0,0 @@ - -#define SC_MEMMGR_CC - -#include -#include "sc_memmgr.h" - -#include -#include - -#include -#include - -#ifdef SC_MEMMGR_ENABLE_CHECKS - -/** - sc_memmgr_error definition -*/ -class sc_memmgr_error { - private: - std::string _srcfile; - unsigned int _srcline; - unsigned int _occurences; - public: - sc_memmgr_error( const std::string & file, const unsigned int line ); - sc_memmgr_error( const sc_memmgr_error & rhs ); - ~sc_memmgr_error( void ); - - bool operator<( const sc_memmgr_error & rhs ) const; - - std::string getsrcfile( void ) const; - unsigned int getsrcline( void ) const; - unsigned int getoccurences( void ) const; -}; - -typedef std::set sc_memmgr_errors; -typedef std::set::iterator sc_memmgr_error_iterator; - -/** - sc_memmgr_record definition -*/ -class sc_memmgr_record { - private: - void * _addr; - size_t _size; - std::string _srcfile; - unsigned int _srcline; - public: - sc_memmgr_record( void * addr, size_t size, const char * file, const unsigned int line ); - sc_memmgr_record( void * addr ); - sc_memmgr_record( const sc_memmgr_record & rhs ); - ~sc_memmgr_record( void ); - - bool operator<( const sc_memmgr_record & rhs ) const; - - void * getaddr( void ) const; - size_t getsize( void ) const; - std::string getsrcfile( void ) const; - unsigned int getsrcline( void ) const; -}; - -typedef std::set sc_memmgr_records; -typedef std::set::iterator sc_memmgr_record_iterator; - -#endif /* SC_MEMMGR_ENABLE_CHECKS */ - -/** - sc_memmgr definition -*/ -class sc_memmgr { - private: -#ifdef SC_MEMMGR_ENABLE_CHECKS - bool _record_insert_busy, _record_erase_busy; - // memory allocation/reallocation records, inserted at allocation, erased at deallocation. - sc_memmgr_records _records; - // memory stats - unsigned int _allocated; // amount of memory allocated simultaniously - unsigned int _maximum_allocated; // maximum amount of memory allocated simultaniously - unsigned int _allocated_total; // total amount of memory allocated in bytes - unsigned int _reallocated_total; // total amount of memory reallocated in bytes - unsigned int _deallocated_total; // total amount of memory deallocated in bytes -#endif /* SC_MEMMGR_ENABLE_CHECKS */ - protected: - public: - sc_memmgr( void ); - ~sc_memmgr( void ); - - void * allocate( size_t size, const char * file, const int line ); - void * reallocate( void * addr, size_t size, const char * file, const int line ); - void deallocate( void * addr, const char * file, const int line ); -}; - -/** - sc_memmgr instance. - There should be one static instance of memmgr. - This instance is automatically destroyed when application exits, so this allows us to add - memory leak detection in it's destructor. -*/ -sc_memmgr memmgr; - -/** - c memory functions implementation -*/ -extern "C" { - - void * sc_malloc_fn( unsigned int size, const char * file, const int line ) { - return memmgr.allocate( size, file, line ); - } - - void * sc_calloc_fn( unsigned int count, unsigned int size, const char * file, const int line ) { - return memmgr.allocate( count * size, file, line ); - } - - void * sc_realloc_fn( void * addr, unsigned int size, const char * file, const int line ) { - return memmgr.reallocate( addr, size, file, line ); - } - - void sc_free_fn( void * addr ) { - memmgr.deallocate( addr, "", 0 ); - } - -} - -/** - c++ memory operators implementation -*/ -void * sc_operator_new( size_t size, const char * file, const int line ) { - return memmgr.allocate( size, file, line ); -} - -void sc_operator_delete( void * addr, const char * file, const int line ) { - memmgr.deallocate( addr, file, line ); -} - -void sc_operator_delete( void * addr ) { - memmgr.deallocate( addr, "", 0 ); -} - -/** - sc_memmgr implementation -*/ -sc_memmgr::sc_memmgr( void ) { -#ifdef SC_MEMMGR_ENABLE_CHECKS - _record_insert_busy = false; - _record_erase_busy = false; - - _allocated = 0; - _maximum_allocated = 0; - _allocated_total = 0; - _reallocated_total = 0; - _deallocated_total = 0; -#endif /* SC_MEMMGR_ENABLE_CHECKS */ -} - -/** - Destructor: - sc_memmgr::~sc_memmgr(void) - Description: - The sc_memmgr destructor is used to check for memory leaks when enabled. - All records still present when sc_memmgr instance is destroyed can be considered as - memory leaks. -*/ -sc_memmgr::~sc_memmgr( void ) { -#ifdef SC_MEMMGR_ENABLE_CHECKS - sc_memmgr_record_iterator irecord; - sc_memmgr_errors errors; - sc_memmgr_error_iterator ierror; - - // Check if total allocated equals total deallocated - if( _allocated_total != _deallocated_total ) { - // todo: generate warning for possible memory leaks, enable full memory leak checking - fprintf( stderr, "sc_memmgr warning: Possible memory leaks detected (%d of %d bytes)\n", _allocated_total - _deallocated_total, _allocated_total ); - } - - // Compact leaks into an error list to prevent same leak being reported multiple times. - _record_insert_busy = true; - _record_erase_busy = true; - for( irecord = _records.begin(); - irecord != _records.end(); - irecord ++ ) { - sc_memmgr_error error( irecord->getsrcfile(), irecord->getsrcline() ); - ierror = errors.find( error ); - if( ierror == errors.end() ) { - errors.insert( error ); - } - //else - // ierror->occurences ++; - } - _record_insert_busy = false; - _record_erase_busy = false; - - // Loop through memory leaks to generate/buffer errors - for( ierror = errors.begin(); - ierror != errors.end(); - ierror ++ ) { - // todo: generate error for memory leak - fprintf( stderr, "sc_memmgr warning: Possible memory leak in %s line %d\n", ierror->getsrcfile().c_str(), ierror->getsrcline() ); - } - - // Clear remaining records - _record_erase_busy = true; - _records.clear(); - errors.clear(); - _record_erase_busy = false; -#endif /* SC_MEMMGR_ENABLE_CHECKS */ -} - -void * sc_memmgr::allocate( size_t size, const char * file, const int line ) { - void * addr; - - // Allocate - addr = malloc( size ); - if( addr == NULL ) { - // todo: error allocation failed - fprintf( stderr, "sc_memmgr error: Memory allocation failed in %s line %d\n", file, line ); - } - - // Some stl implementations (for example debian gcc) use the new operator to construct - // new elements when inserting sc_memmgr_record. When this our new operator gets used - // for this operation, this would result in an infinite loop. This is fixed by the - // _record_insert_busy flag. -#ifdef SC_MEMMGR_ENABLE_CHECKS - if( !_record_insert_busy ) { - // Store record for this allocation - _record_insert_busy = true; - _records.insert( sc_memmgr_record( addr, size, file, line ) ); - _record_insert_busy = false; - - // Update stats - _allocated += size; - if( _allocated > _maximum_allocated ) { - _maximum_allocated = _allocated; - } - _allocated_total += size; - } -#endif /* SC_MEMMGR_ENABLE_CHECKS */ - - return addr; -} - -void * sc_memmgr::reallocate( void * addr, size_t size, const char * file, const int line ) { -#ifdef SC_MEMMGR_ENABLE_CHECKS - sc_memmgr_record_iterator record; - - if( !_record_insert_busy ) { - // Find record of previous allocation/reallocation - record = _records.find( sc_memmgr_record( addr ) ); - if( record == _records.end() ) { - // todo: error reallocating memory not allocated? - fprintf( stderr, "sc_memmgr warning: Reallocation of not allocated memory at %s line %d\n", file, line ); - } else { - // Update stats - _allocated -= record->getsize(); - _deallocated_total += record->getsize(); - - // Erase previous allocation/reallocation - _record_erase_busy = true; - _records.erase( record ); - _record_erase_busy = false; - } - } -#endif /* SC_MEMMGR_ENABLE_CHECKS */ - - // Reallocate - addr = realloc( addr, size ); - if( addr == NULL ) { - // todo: error reallocation failed - fprintf( stderr, "sc_memmgr error: Reallocation failed at %s line %d\n", file, line ); - } - -#ifdef SC_MEMMGR_ENABLE_CHECKS - if( !_record_insert_busy ) { - // Store record for this reallocation - _record_insert_busy = true; - _records.insert( sc_memmgr_record( addr, size, file, line ) ); - _record_insert_busy = false; - - // Update stats - _allocated += size; - if( _allocated > _maximum_allocated ) { - _maximum_allocated = _allocated; - } - _allocated_total += size; - _reallocated_total += size; - } -#endif /* SC_MEMMGR_ENABLE_CHECKS */ - - return addr; -} - -void sc_memmgr::deallocate( void * addr, const char * file, const int line ) { -#ifdef SC_MEMMGR_ENABLE_CHECKS - sc_memmgr_record_iterator record; - - if( !_record_erase_busy ) { - // Find record of previous allocation/reallocation - record = _records.find( sc_memmgr_record( addr ) ); - if( record == _records.end() ) { - // todo: error free called for not allocated memory? - fprintf( stderr, "sc_memmgr warning: Deallocate of not allocated memory at %s line %d\n", file, line ); - } else { - // Update stats - _allocated -= record->getsize(); - _deallocated_total += record->getsize(); - - // Erase record - _record_erase_busy = true; - _records.erase( record ); - _record_erase_busy = false; - } - } -#else - (void) file; // quell unused param warnings - (void) line; -#endif /* SC_MEMMGR_ENABLE_CHECKS */ - - // Deallocate - free( addr ); -} - -#ifdef SC_MEMMGR_ENABLE_CHECKS -/** - sc_memmgr_error implementation -*/ -sc_memmgr_error::sc_memmgr_error( const std::string & file, const unsigned int line ) { - _srcfile = file; - _srcline = line; - _occurences = 1; -} - -sc_memmgr_error::sc_memmgr_error( const sc_memmgr_error & rhs ) { - _srcfile = rhs._srcfile; - _srcline = rhs._srcline; - _occurences = rhs._occurences; -} - -sc_memmgr_error::~sc_memmgr_error( void ) { -} - -bool sc_memmgr_error::operator<( const sc_memmgr_error & rhs ) const { - if( _srcfile == rhs._srcfile ) { - return _srcline < rhs._srcline; - } - return _srcfile < rhs._srcfile; -} - -std::string sc_memmgr_error::getsrcfile( void ) const { - return _srcfile; -} - -unsigned int sc_memmgr_error::getsrcline( void ) const { - return _srcline; -} - -unsigned int sc_memmgr_error::getoccurences( void ) const { - return _occurences; -} - -/** - sc_memmgr_record implementation -*/ -sc_memmgr_record::sc_memmgr_record( void * addr, size_t size, const char * file, const unsigned int line ) { - _addr = addr; - _size = size; - _srcfile = file; - _srcline = line; -} - -sc_memmgr_record::sc_memmgr_record( void * addr ) { - _addr = addr; - _size = 0; - _srcfile = ""; - _srcline = -1; -} - -sc_memmgr_record::sc_memmgr_record( const sc_memmgr_record & rhs ) { - _addr = rhs._addr; - _size = rhs._size; - _srcfile = rhs._srcfile; - _srcline = rhs._srcline; -} - -sc_memmgr_record::~sc_memmgr_record( void ) { -} - -bool sc_memmgr_record::operator<( const sc_memmgr_record & rhs ) const { - return _addr < rhs._addr; -} - -void * sc_memmgr_record::getaddr( void ) const { - return _addr; -} - -size_t sc_memmgr_record::getsize( void ) const { - return _size; -} - -std::string sc_memmgr_record::getsrcfile( void ) const { - return _srcfile; -} - -unsigned int sc_memmgr_record::getsrcline( void ) const { - return _srcline; -} - -#endif /* SC_MEMMGR_ENABLE_CHECKS */ diff --git a/src/base/sc_memmgr.h b/src/base/sc_memmgr.h deleted file mode 100644 index e9ecddcb2..000000000 --- a/src/base/sc_memmgr.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef SC_MEMMGR_H -#define SC_MEMMGR_H - -#include -#include - -#if defined(SC_MEMMGR_ENABLE_CHECKS) - -/** - Platform specific defines -*/ -#if defined(__MSVC__) || defined(__BORLAND__) -#define THROW_STD_BAD_ALLOC -#define THROW_EMPTY -#else -#define THROW_STD_BAD_ALLOC throw (std::bad_alloc) -#define THROW_EMPTY throw () -#endif - -#ifdef __cplusplus -#include -extern "C" { -#endif /* __cplusplus */ - - SC_BASE_EXPORT void * sc_malloc_fn( unsigned int size, const char * file, const int line ); - SC_BASE_EXPORT void * sc_calloc_fn( unsigned int count, unsigned int size, const char * file, const int line ); - SC_BASE_EXPORT void * sc_realloc_fn( void * addr, unsigned int size, const char * file, const int line ); - SC_BASE_EXPORT void sc_free_fn( void * addr ); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#ifdef __cplusplus - -SC_BASE_EXPORT void * sc_operator_new( size_t size, const char * file, const int line ); -SC_BASE_EXPORT void sc_operator_delete( void * addr, const char * file, const int line ); -SC_BASE_EXPORT void sc_operator_delete( void * addr ); - -#endif /* __cplusplus */ - -#ifndef SC_MEMMGR_CC - -#define sc_malloc(size) sc_malloc_fn(size, __FILE__, __LINE__) -#define sc_calloc(count, size) sc_calloc_fn(count, size, __FILE__, __LINE__) -#define sc_realloc(addr, size) sc_realloc_fn(addr, size, __FILE__, __LINE__) -#define sc_free(addr) sc_free_fn(addr) - -#ifdef __cplusplus - -#include - -inline void * operator new( size_t size, const char * file, const int line ) THROW_STD_BAD_ALLOC { - return sc_operator_new( size, file, line ); -} - -inline void * operator new[]( size_t size, const char * file, const int line ) THROW_STD_BAD_ALLOC { - return sc_operator_new( size, file, line ); -} - -inline void operator delete( void * addr, const char * file, const int line ) THROW_STD_BAD_ALLOC { - sc_operator_delete( addr, file, line ); -} - -inline void operator delete[]( void * addr, const char * file, const int line ) THROW_STD_BAD_ALLOC { - sc_operator_delete( addr, file, line ); -} - -inline void operator delete( void * addr ) THROW_EMPTY { - sc_operator_delete( addr ); -} - -inline void operator delete[]( void * addr ) THROW_EMPTY { - sc_operator_delete( addr ); -} - -#define new new(__FILE__, __LINE__) - -#endif /* __cplusplus */ - -#endif /* SC_MEMMGR_CC */ - -#else -#define sc_malloc(size) malloc(size) -#define sc_calloc(count, size) calloc(count, size) -#define sc_realloc(addr, size) realloc(addr, size) -#define sc_free(addr) free(addr) -#endif /* SC_MEMMGR_ENABLE_CHECKS */ - -#endif /* SC_MEMMGR_H */ diff --git a/src/base/sc_mkdir.c b/src/base/sc_mkdir.c deleted file mode 100644 index 1a908155c..000000000 --- a/src/base/sc_mkdir.c +++ /dev/null @@ -1,32 +0,0 @@ - -#include "sc_mkdir.h" - -#include -#include -#include -#ifdef _WIN32 -# include -#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; -} diff --git a/src/base/sc_mkdir.h b/src/base/sc_mkdir.h deleted file mode 100644 index 21c8d9c5c..000000000 --- a/src/base/sc_mkdir.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SC_MKDIR -#define SC_MKDIR - -#include - -/** 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 */ diff --git a/src/base/sc_nullptr.h b/src/base/sc_nullptr.h deleted file mode 100644 index 342397001..000000000 --- a/src/base/sc_nullptr.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef NULLPTR_H -#define NULLPTR_H - -#include - -#ifdef HAVE_NULLPTR -#include -#else -# define nullptr_t void* -# define nullptr NULL -#endif //HAVE_NULLPTR - -#endif //NULLPTR_H diff --git a/src/base/sc_strtoull.h b/src/base/sc_strtoull.h deleted file mode 100644 index b68b76707..000000000 --- a/src/base/sc_strtoull.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef SC_STRTOULL_H -#define SC_STRTOULL_H - -#include - -#ifdef _WIN32 -# define strtoull _strtoui64 -# define ULLONG_MAX _UI64_MAX -#endif - -#endif /* SC_STRTOULL_H */ diff --git a/src/cldai/CMakeLists.txt b/src/cldai/CMakeLists.txt index 4630296a3..e37ac06d2 100644 --- a/src/cldai/CMakeLists.txt +++ b/src/cldai/CMakeLists.txt @@ -1,5 +1,4 @@ - -set(LIBSTEPDAI_SRCS +set(DAI_SRCS sdaiApplication_instance_set.cc sdaiBinary.cc sdaiDaObject.cc @@ -13,31 +12,23 @@ set(LIBSTEPDAI_SRCS sdaiString.cc ) -SET(SC_CLDAI_HDRS - sdaiApplication_instance_set.h - sdaiBinary.h - sdaiDaObject.h - sdaiEntity_extent.h - sdaiEntity_extent_set.h - sdaiEnum.h - sdaiModel_contents.h - sdaiModel_contents_list.h - sdaiObject.h - sdaiSession_instance.h - sdaiString.h - ) - include_directories( ${CMAKE_CURRENT_SOURCE_DIR} - ${SC_SOURCE_DIR}/src/base - ${SC_SOURCE_DIR}/src/clstepcore - ${SC_SOURCE_DIR}/src/clutils + ${CMAKE_SOURCE_DIR}/include/stepcode ) -SC_ADDLIB(stepdai "${LIBSTEPDAI_SRCS}" "steputils;base") +set(_libdeps steputils) + +if(BUILD_SHARED_LIBS) + SC_ADDLIB(stepdai SHARED SOURCES ${DAI_SRCS} LINK_LIBRARIES ${_libdeps}) + if(WIN32) + target_compile_definitions(stepdai PRIVATE SC_DAI_DLL_EXPORTS) + endif() +endif() -install(FILES ${SC_CLDAI_HDRS} - DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cldai) +if(BUILD_STATIC_LIBS) + SC_ADDLIB(stepdai-static STATIC SOURCES ${DAI_SRCS} LINK_LIBRARIES $-static) +endif() # Local Variables: # tab-width: 8 diff --git a/src/cldai/sdaiApplication_instance_set.cc b/src/cldai/sdaiApplication_instance_set.cc index 30a9103f4..f1733d40d 100644 --- a/src/cldai/sdaiApplication_instance_set.cc +++ b/src/cldai/sdaiApplication_instance_set.cc @@ -24,14 +24,13 @@ * UArray implementation. */ -//#include -#include +//#include "cldai/sdaiApplication_instance_set.h" +#include "clstepcore/sdai.h" #include #include -#include "sc_memmgr.h" -#include "sdaiApplication_instance.h" +#include "clstepcore/sdaiApplication_instance.h" // to help ObjectCenter #ifndef HAVE_MEMMOVE diff --git a/src/cldai/sdaiBinary.cc b/src/cldai/sdaiBinary.cc index 678add01c..e9c384f74 100644 --- a/src/cldai/sdaiBinary.cc +++ b/src/cldai/sdaiBinary.cc @@ -10,8 +10,7 @@ */ #include -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" SDAI_Binary::SDAI_Binary( const char * str, int max ) { content = std::string( str, max ); diff --git a/src/cldai/sdaiDaObject.cc b/src/cldai/sdaiDaObject.cc index 2f43ab284..52f06fc16 100644 --- a/src/cldai/sdaiDaObject.cc +++ b/src/cldai/sdaiDaObject.cc @@ -2,8 +2,7 @@ #include #include -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" // to help ObjectCenter #ifndef HAVE_MEMMOVE diff --git a/src/cldai/sdaiEntity_extent.cc b/src/cldai/sdaiEntity_extent.cc index f98d5d279..7c27ea6e4 100644 --- a/src/cldai/sdaiEntity_extent.cc +++ b/src/cldai/sdaiEntity_extent.cc @@ -2,8 +2,7 @@ //#include -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" SDAI_Entity_extent::SDAI_Entity_extent( ) : _definition( 0 ), _definition_name( 0 ), _owned_by( 0 ) { @@ -56,7 +55,7 @@ void SDAI_Entity_extent::owned_by_( SDAI_Model_contents__list_var& mclv ) { } SDAI_Model_contents__list_var SDAI_Entity_extent ::owned_by_() const { - return ( const SDAI_Model_contents__list_var ) &_owned_by; + return ( SDAI_Model_contents__list_var ) &_owned_by; } /* diff --git a/src/cldai/sdaiEntity_extent_set.cc b/src/cldai/sdaiEntity_extent_set.cc index af3658222..4080e336b 100644 --- a/src/cldai/sdaiEntity_extent_set.cc +++ b/src/cldai/sdaiEntity_extent_set.cc @@ -26,8 +26,7 @@ #include #include -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" /* #include @@ -51,7 +50,7 @@ SDAI_Entity_extent__set::SDAI_Entity_extent__set( int defaultSize ) { } SDAI_Entity_extent__set::~SDAI_Entity_extent__set() { - delete _buf; + delete[] _buf; } void SDAI_Entity_extent__set::Check( int index ) { @@ -62,7 +61,7 @@ void SDAI_Entity_extent__set::Check( int index ) { _bufsize = ( index + 1 ) * 2; newbuf = new SDAI_Entity_extent_ptr[_bufsize]; memmove( newbuf, _buf, _count * sizeof( SDAI_Entity_extent_ptr ) ); - delete _buf; + delete[] _buf; _buf = newbuf; } } diff --git a/src/cldai/sdaiEnum.cc b/src/cldai/sdaiEnum.cc index a8e37d407..8228855b5 100644 --- a/src/cldai/sdaiEnum.cc +++ b/src/cldai/sdaiEnum.cc @@ -1,6 +1,5 @@ -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" /* * NIST STEP Core Class Library @@ -313,6 +312,11 @@ SDAI_BOOLEAN & SDAI_BOOLEAN::operator= ( const SDAI_LOGICAL & t ) { return *this; } +SDAI_BOOLEAN & SDAI_BOOLEAN::operator= ( const SDAI_BOOLEAN & t ) { + v = t; + return *this; +} + SDAI_BOOLEAN & SDAI_BOOLEAN::operator= ( const Boolean t ) { v = t; return *this; diff --git a/src/cldai/sdaiModel_contents.cc b/src/cldai/sdaiModel_contents.cc index 67140916a..3cb0828a0 100644 --- a/src/cldai/sdaiModel_contents.cc +++ b/src/cldai/sdaiModel_contents.cc @@ -1,6 +1,5 @@ -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" ///////// SDAI_Model_contents_instances @@ -27,7 +26,7 @@ SDAI_Model_contents::instances_() { SDAI_Model_contents_instances_ptr SDAI_Model_contents::instances_() const { - return ( const SDAI_Model_contents_instances_ptr ) &_instances; + return ( SDAI_Model_contents_instances_ptr ) &_instances; } SDAI_Entity_extent__set_var @@ -37,7 +36,7 @@ SDAI_Model_contents::folders_() { SDAI_Entity_extent__set_var SDAI_Model_contents::folders_() const { - return ( const SDAI_Entity_extent__set_var )&_folders; + return ( SDAI_Entity_extent__set_var )&_folders; } SDAI_Entity_extent__set_var @@ -47,7 +46,7 @@ SDAI_Model_contents::populated_folders_() { SDAI_Entity_extent__set_var SDAI_Model_contents::populated_folders_() const { - return ( const SDAI_Entity_extent__set_var )&_populated_folders; + return ( SDAI_Entity_extent__set_var )&_populated_folders; } SDAI_PID_DA_ptr SDAI_Model_contents::get_object_pid( const SDAI_DAObject_ptr & d ) const { diff --git a/src/cldai/sdaiModel_contents_list.cc b/src/cldai/sdaiModel_contents_list.cc index 8f6440e8e..62197b190 100644 --- a/src/cldai/sdaiModel_contents_list.cc +++ b/src/cldai/sdaiModel_contents_list.cc @@ -23,8 +23,7 @@ /* * UArray implementation. */ -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" // to help ObjectCenter #ifndef HAVE_MEMMOVE diff --git a/src/cldai/sdaiObject.cc b/src/cldai/sdaiObject.cc index 14cf6c26a..fd930881c 100644 --- a/src/cldai/sdaiObject.cc +++ b/src/cldai/sdaiObject.cc @@ -1,5 +1,4 @@ -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" SDAI_sdaiObject::SDAI_sdaiObject() { } diff --git a/src/cldai/sdaiSession_instance.cc b/src/cldai/sdaiSession_instance.cc index 6f48be442..291c0c21b 100644 --- a/src/cldai/sdaiSession_instance.cc +++ b/src/cldai/sdaiSession_instance.cc @@ -1,5 +1,4 @@ -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" SDAI_Session_instance::SDAI_Session_instance() { } diff --git a/src/cldai/sdaiString.cc b/src/cldai/sdaiString.cc index 664a39358..06f94d9e6 100644 --- a/src/cldai/sdaiString.cc +++ b/src/cldai/sdaiString.cc @@ -9,9 +9,8 @@ * and is not subject to copyright. */ -#include +#include "clstepcore/sdai.h" #include -#include "sc_memmgr.h" SDAI_String::SDAI_String( const char * str, size_t max ) { if( !str ) { @@ -41,6 +40,11 @@ SDAI_String & SDAI_String::operator= ( const char * s ) { return *this; } +SDAI_String & SDAI_String::operator= ( const SDAI_String & s ) { + content = s.content; + return *this; +} + bool SDAI_String::operator== ( const char * s ) const { return ( content == s ); } diff --git a/src/cleditor/CMakeLists.txt b/src/cleditor/CMakeLists.txt index dafbfd6af..2b306068e 100644 --- a/src/cleditor/CMakeLists.txt +++ b/src/cleditor/CMakeLists.txt @@ -1,5 +1,4 @@ - -set(LIBSTEPEDITOR_SRCS +set(EDITOR_SRCS STEPfile.cc STEPfile.inline.cc cmdmgr.cc @@ -9,28 +8,21 @@ set(LIBSTEPEDITOR_SRCS SdaiSchemaInit.cc ) -SET(SC_CLEDITOR_HDRS - STEPfile.h - cmdmgr.h - editordefines.h - SdaiHeaderSchema.h - SdaiHeaderSchemaClasses.h - SdaiSchemaInit.h - seeinfodefault.h - ) - include_directories( ${CMAKE_CURRENT_SOURCE_DIR} - ${SC_SOURCE_DIR}/src/base - ${SC_SOURCE_DIR}/src/cldai - ${SC_SOURCE_DIR}/src/clstepcore - ${SC_SOURCE_DIR}/src/clutils + ${CMAKE_SOURCE_DIR}/include/stepcode ) -SC_ADDLIB(stepeditor "${LIBSTEPEDITOR_SRCS}" "stepcore;stepdai;steputils;base") +if(BUILD_SHARED_LIBS) + SC_ADDLIB(stepeditor SHARED SOURCES ${EDITOR_SRCS} LINK_LIBRARIES stepcore stepdai steputils) + if(WIN32) + target_compile_definitions(stepeditor PRIVATE SC_EDITOR_DLL_EXPORTS) + endif() +endif() -install(FILES ${SC_CLEDITOR_HDRS} - DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cleditor) +if(BUILD_STATIC_LIBS) + SC_ADDLIB(stepeditor-static STATIC SOURCES ${EDITOR_SRCS} LINK_LIBRARIES stepcore-static stepdai-static steputils-static) +endif() # Local Variables: # tab-width: 8 diff --git a/src/cleditor/README b/src/cleditor/README index 98b2011bc..8cacccd43 100644 --- a/src/cleditor/README +++ b/src/cleditor/README @@ -1,6 +1,6 @@ This directory contains source code defining a collection of application independent classes supporting the editing of STEP -instance data. This library includes functions for editing +instance data. This library includes functions for editing individual instances and for manipulating groups of instances. The editor library acts as an intermediary between the core library and a graphical user interface library. diff --git a/src/cleditor/STEPfile.cc b/src/cleditor/STEPfile.cc index f7f4b2818..a05ef9a7f 100644 --- a/src/cleditor/STEPfile.cc +++ b/src/cleditor/STEPfile.cc @@ -24,17 +24,15 @@ #include #include -#include -#include -#include -#include -#include +#include "cleditor/STEPfile.h" +#include "clstepcore/sdai.h" +#include "clstepcore/STEPcomplex.h" +#include "clstepcore/STEPattribute.h" +#include "cleditor/SdaiHeaderSchema.h" // STEPundefined contains // void PushPastString (istream& in, std::string &s, ErrorDescriptor *err) -#include - -#include "sc_memmgr.h" +#include "clstepcore/STEPundefined.h" /** * \returns The new file name for the class. @@ -101,7 +99,7 @@ float STEPfile::GetWriteProgress() const { * returns an error descriptor. * It expects to find the "HEADER;" symbol at the beginning of the istream. * - * side effects: The function gobbles all characters up to and including the + * side effects: The function gobbles all characters up to and including the * next "ENDSEC;" from in. * The STEPfile::_headerInstances may change. */ @@ -117,7 +115,7 @@ Severity STEPfile::ReadHeader( istream & in ) { int fileid; std::string keywd; char c = '\0'; - char buf [BUFSIZ]; + char buf [BUFSIZ+1]; std::string strbuf; @@ -341,7 +339,7 @@ SDAI_Application_instance * STEPfile::HeaderDefaultFileSchema() { * If the _headerInstances contain no instances, then copy the instances * from im onto the _headerInstances. * This only works for an instance manager which contains the following - * header section entites. The file id numbers are important. + * header section entities. The file id numbers are important. * * #1 = FILE_DESCRIPTION * #2 = FILE_NAME @@ -442,7 +440,7 @@ int STEPfile::ReadData1( istream & in ) { char c; int instance_count = 0; - char buf[BUFSIZ]; + char buf[BUFSIZ+1]; buf[0] = '\0'; std::string tmpbuf; @@ -565,7 +563,7 @@ int STEPfile::ReadData2( istream & in, bool useTechCor ) { _warningCount = 0; // reset error count char c; - char buf[BUFSIZ]; + char buf[BUFSIZ+1]; buf[0] = '\0'; std::string tmpbuf; @@ -730,7 +728,7 @@ int STEPfile::FindDataSection( istream & in ) { } int STEPfile::FindHeaderSection( istream & in ) { - char buf[BUFSIZ]; + char buf[BUFSIZ+1]; char * b = buf; *b = '\0'; @@ -851,6 +849,8 @@ SDAI_Application_instance * STEPfile::CreateInstance( istream & in, ostream & ou << " User Defined Entity in DATA section ignored.\n" << "\tData lost: \'!" << objnm << "\': " << tmpbuf << endl; + if (scopelist) + delete[] scopelist; return ENTITY_NULL; } else { schnm = schemaName(); @@ -879,6 +879,8 @@ SDAI_Application_instance * STEPfile::CreateInstance( istream & in, ostream & ou out << "ERROR: instance #" << fileid << " \'" << objnm << "\': " << result.UserMsg() << ".\n\tData lost: " << tmpbuf << "\n\n"; + if (scopelist) + delete[] scopelist; return ENTITY_NULL; } obj -> STEPfile_id = fileid; @@ -887,6 +889,10 @@ SDAI_Application_instance * STEPfile::CreateInstance( istream & in, ostream & ou SkipInstance( in, tmpbuf ); ReadTokenSeparator( in ); + + if (scopelist) + delete[] scopelist; + return obj; } @@ -1150,7 +1156,7 @@ SDAI_Application_instance * STEPfile::ReadInstance( istream & in, ostream & out, Severity sev = SEVERITY_NULL; std::string tmpbuf; - char errbuf[BUFSIZ]; + char errbuf[BUFSIZ+1]; errbuf[0] = '\0'; std::string currSch; std::string objnm; @@ -1531,9 +1537,11 @@ void STEPfile::WriteHeaderInstance( SDAI_Application_instance * obj, ostream & o void STEPfile::WriteHeaderInstanceFileName( ostream & out ) { // Get the FileName instance from _headerInstances SDAI_Application_instance * se = 0; + bool del_se = false; se = _headerInstances->GetApplication_instance( "File_Name" ); if( se == ENTITY_NULL ) { se = ( SDAI_Application_instance * )HeaderDefaultFileName(); + del_se = true; } //set some of the attribute values at time of output @@ -1553,6 +1561,9 @@ void STEPfile::WriteHeaderInstanceFileName( ostream & out ) { //output the values to the file WriteHeaderInstance( se, out ); + + if (del_se) + delete se; } void STEPfile::WriteHeaderInstanceFileDescription( ostream & out ) { @@ -1563,8 +1574,11 @@ void STEPfile::WriteHeaderInstanceFileDescription( ostream & out ) { // ERROR: no File_Name instance in _headerInstances // create a File_Name instance se = ( SDAI_Application_instance * )HeaderDefaultFileDescription(); + WriteHeaderInstance(se, out); + delete se; + } else { + WriteHeaderInstance( se, out ); } - WriteHeaderInstance( se, out ); } void STEPfile::WriteHeaderInstanceFileSchema( ostream & out ) { @@ -1575,8 +1589,11 @@ void STEPfile::WriteHeaderInstanceFileSchema( ostream & out ) { // ERROR: no File_Name instance in _headerInstances // create a File_Name instance se = ( SDAI_Application_instance * ) HeaderDefaultFileSchema(); + WriteHeaderInstance( se, out ); + delete se; + } else { + WriteHeaderInstance( se, out ); } - WriteHeaderInstance( se, out ); } void STEPfile::WriteData( ostream & out, int writeComments ) { @@ -1603,7 +1620,7 @@ void STEPfile::WriteValuePairsData( ostream & out, int writeComments, int mixedC Severity STEPfile::AppendFile( istream * in, bool useTechCor ) { Severity rval = SEVERITY_NULL; - char errbuf[BUFSIZ]; + char errbuf[BUFSIZ+1]; SetFileIdIncrement(); int total_insts = 0, valid_insts = 0; diff --git a/src/cleditor/STEPfile.inline.cc b/src/cleditor/STEPfile.inline.cc index 2d4e6d9dd..86af07564 100644 --- a/src/cleditor/STEPfile.inline.cc +++ b/src/cleditor/STEPfile.inline.cc @@ -11,13 +11,12 @@ * and is not subject to copyright. */ -#include -#include -#include +#include "cleditor/STEPfile.h" +#include "cleditor/SdaiHeaderSchema.h" +#include "clstepcore/STEPaggregate.h" #include #include -#include "sc_memmgr.h" extern void HeaderSchemaInit( Registry & reg ); @@ -85,7 +84,7 @@ int STEPfile::SetFileType( FileTypeCode ft ) { ** from filename */ std::string STEPfile::TruncFileName( const std::string filename ) const { -#if defined(__WIN32__) && !defined(__mingw32__) +#if defined(_WIN32) && !defined(__mingw32__) char slash = '\\'; #else char slash = '/'; @@ -179,7 +178,7 @@ istream * STEPfile::OpenInputFile( const std::string filename ) { return( 0 ); } else { if( SetFileName( filename ).empty() && ( filename.compare( "-" ) != 0 ) ) { - char msg[BUFSIZ]; + char msg[BUFSIZ+1]; sprintf( msg, "Unable to find file for input: \'%s\'. File not read.\n", filename.c_str() ); _error.AppendToUserMsg( msg ); _error.GreaterSeverity( SEVERITY_INPUT_ERROR ); @@ -196,7 +195,7 @@ istream * STEPfile::OpenInputFile( const std::string filename ) { } if( !in || !( in -> good() ) ) { - char msg[BUFSIZ]; + char msg[BUFSIZ+1]; sprintf( msg, "Unable to open file for input: \'%s\'. File not read.\n", filename.c_str() ); _error.AppendToUserMsg( msg ); _error.GreaterSeverity( SEVERITY_INPUT_ERROR ); @@ -231,7 +230,7 @@ ofstream * STEPfile::OpenOutputFile( std::string filename ) { } } else { if( SetFileName( filename ).empty() ) { - char msg[BUFSIZ]; + char msg[BUFSIZ+1]; sprintf( msg, "can't find file: %s\nFile not written.\n", filename.c_str() ); _error.AppendToUserMsg( msg ); _error.GreaterSeverity( SEVERITY_INPUT_ERROR ); diff --git a/src/cleditor/SdaiHeaderSchema.cc b/src/cleditor/SdaiHeaderSchema.cc index 6c96a2d2c..73212bc48 100644 --- a/src/cleditor/SdaiHeaderSchema.cc +++ b/src/cleditor/SdaiHeaderSchema.cc @@ -10,10 +10,9 @@ extern ofstream * logStream; #define SCLLOGFILE "scl.log" #endif -#include -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/STEPattribute.h" +#include "cleditor/SdaiHeaderSchema.h" Schema * s_header_section_schema = 0; @@ -62,7 +61,7 @@ SdaiSection_language::SdaiSection_language( SDAI_Application_instance * se, int /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -72,7 +71,7 @@ SdaiSection_language::SdaiSection_language( SDAI_Application_instance * se, int /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -144,7 +143,7 @@ SdaiFile_population::SdaiFile_population( SDAI_Application_instance * se, int * /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -154,7 +153,7 @@ SdaiFile_population::SdaiFile_population( SDAI_Application_instance * se, int * /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -164,7 +163,7 @@ SdaiFile_population::SdaiFile_population( SDAI_Application_instance * se, int * /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -264,7 +263,7 @@ SdaiFile_name::SdaiFile_name( SDAI_Application_instance * se, int * addAttrs ) { /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -274,7 +273,7 @@ SdaiFile_name::SdaiFile_name( SDAI_Application_instance * se, int * addAttrs ) { /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -284,7 +283,7 @@ SdaiFile_name::SdaiFile_name( SDAI_Application_instance * se, int * addAttrs ) { /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -294,7 +293,7 @@ SdaiFile_name::SdaiFile_name( SDAI_Application_instance * se, int * addAttrs ) { /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -304,7 +303,7 @@ SdaiFile_name::SdaiFile_name( SDAI_Application_instance * se, int * addAttrs ) { /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -314,7 +313,7 @@ SdaiFile_name::SdaiFile_name( SDAI_Application_instance * se, int * addAttrs ) { /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -324,7 +323,7 @@ SdaiFile_name::SdaiFile_name( SDAI_Application_instance * se, int * addAttrs ) { /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -452,7 +451,7 @@ SdaiSection_context::SdaiSection_context( SDAI_Application_instance * se, int * /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -462,7 +461,7 @@ SdaiSection_context::SdaiSection_context( SDAI_Application_instance * se, int * /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -530,7 +529,7 @@ SdaiFile_description::SdaiFile_description( SDAI_Application_instance * se, int /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -540,7 +539,7 @@ SdaiFile_description::SdaiFile_description( SDAI_Application_instance * se, int /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } @@ -604,7 +603,7 @@ SdaiFile_schema::SdaiFile_schema( SDAI_Application_instance * se, int * addAttrs /*access functions still work. */ attributes.push( a ); /* Put attribute on the attributes list for the */ - /* main inheritance heirarchy. */ + /* main inheritance hierarchy. */ if( !addAttrs || addAttrs[0] ) { se->attributes.push( a ); } diff --git a/src/cleditor/SdaiHeaderSchemaAll.cc b/src/cleditor/SdaiHeaderSchemaAll.cc index 3a469c7d3..cf88eb3aa 100644 --- a/src/cleditor/SdaiHeaderSchemaAll.cc +++ b/src/cleditor/SdaiHeaderSchemaAll.cc @@ -4,8 +4,7 @@ // it since your modifications will be lost if exp2cxx is used to // regenerate it. -#include -#include "sc_memmgr.h" +#include "cleditor/SdaiHeaderSchema.h" void HeaderInitSchemasAndEnts( Registry & reg ) { Uniqueness_rule_ptr ur; diff --git a/src/cleditor/SdaiHeaderSchemaInit.cc b/src/cleditor/SdaiHeaderSchemaInit.cc index 35099d805..32b1655d1 100644 --- a/src/cleditor/SdaiHeaderSchemaInit.cc +++ b/src/cleditor/SdaiHeaderSchemaInit.cc @@ -4,11 +4,10 @@ // it since your modifications will be lost if exp2cxx is used to // regenerate it. -#include -#include -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/Registry.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/STEPattribute.h" +#include "cleditor/SdaiHeaderSchema.h" void SdaiHEADER_SECTION_SCHEMAInit( Registry & reg ) { header_section_schemat_time_stamp_text->ReferentType( t_sdaiSTRING ); diff --git a/src/cleditor/SdaiSchemaInit.cc b/src/cleditor/SdaiSchemaInit.cc index 05790a09c..82323987a 100644 --- a/src/cleditor/SdaiSchemaInit.cc +++ b/src/cleditor/SdaiSchemaInit.cc @@ -4,8 +4,7 @@ // it since your modifications will be lost if exp2cxx is used to // regenerate it. -#include -#include "sc_memmgr.h" +#include "cleditor/SdaiSchemaInit.h" void HeaderSchemaInit( Registry & reg ) { HeaderInitSchemasAndEnts( reg ); diff --git a/src/cleditor/cmdmgr.cc b/src/cleditor/cmdmgr.cc index 7c015ce47..4b78d4f90 100644 --- a/src/cleditor/cmdmgr.cc +++ b/src/cleditor/cmdmgr.cc @@ -10,8 +10,7 @@ * and is not subject to copyright. */ -#include -#include "sc_memmgr.h" +#include "cleditor/cmdmgr.h" ReplicateLinkNode * ReplicateList::FindNode( MgrNode * mn ) { ReplicateLinkNode * rln = ( ReplicateLinkNode * )GetHead(); @@ -72,6 +71,16 @@ CmdMgr::CmdMgr() { replicateList = new ReplicateList(); } +CmdMgr::~CmdMgr() { + delete completeList; + delete incompleteList; + delete deleteList; + delete mappedWriteList; + delete mappedViewList; + delete closeList; + delete replicateList; +} + void CmdMgr::ReplicateCmdList( MgrNode * mn ) { if( !( replicateList->IsOnList( mn ) ) ) { replicateList->AddNode( mn ); diff --git a/src/cllazyfile/CMakeLists.txt b/src/cllazyfile/CMakeLists.txt index 1ff85d6e8..c56e8dbbc 100644 --- a/src/cllazyfile/CMakeLists.txt +++ b/src/cllazyfile/CMakeLists.txt @@ -1,44 +1,34 @@ - -set( clLazyFile_SRCS +set(LAZY_SRCS lazyDataSectionReader.cc lazyFileReader.cc lazyInstMgr.cc p21HeaderSectionReader.cc sectionReader.cc lazyP21DataSectionReader.cc - ) - -set( SC_CLLAZYFILE_HDRS - headerSectionReader.h - lazyFileReader.h - lazyP21DataSectionReader.h - p21HeaderSectionReader.h - lazyDataSectionReader.h - lazyInstMgr.h - lazyTypes.h - sectionReader.h - instMgrHelper.h + judy.c ) 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 + ${CMAKE_SOURCE_DIR}/include/stepcode ) -SC_ADDLIB(steplazyfile "${clLazyFile_SRCS};${clLazyFile_HDRS}" "stepcore;stepdai;steputils;base;stepeditor") -SC_ADDEXEC(lazy_test "lazy_test.cc" "steplazyfile;stepeditor" NO_INSTALL) -set_property(TARGET lazy_test APPEND PROPERTY COMPILE_DEFINITIONS "NO_REGISTRY") -if(TARGET lazy_test-static) - set_property(TARGET lazy_test-static APPEND PROPERTY COMPILE_DEFINITIONS "NO_REGISTRY") -endif(TARGET lazy_test-static) +set(_libdeps stepcore stepdai steputils stepeditor) + +if(BUILD_SHARED_LIBS) + SC_ADDLIB(steplazyfile SHARED SOURCES ${LAZY_SRCS} LINK_LIBRARIES ${_libdeps}) + if(WIN32) + target_compile_definitions(steplazyfile PRIVATE SC_LAZYFILE_DLL_EXPORTS) + endif() +endif() + +if(BUILD_STATIC_LIBS) + set(_libdeps stepcore-static stepdai-static steputils-static stepeditor-static) + SC_ADDLIB(steplazyfile-static STATIC SOURCES ${LAZY_SRCS} LINK_LIBRARIES ${_libdeps}) +endif() -install(FILES ${SC_CLLAZYFILE_HDRS} - DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/cllazyfile) +SC_ADDEXEC(lazy_test SOURCES "lazy_test.cc;sc_benchmark.cc" LINK_LIBRARIES steplazyfile stepeditor NO_INSTALL) +target_compile_definitions(lazy_test PRIVATE NO_REGISTRY) # Local Variables: # tab-width: 8 diff --git a/src/cllazyfile/current_function.hpp b/src/cllazyfile/current_function.hpp index 691cf6964..9e783f003 100644 --- a/src/cllazyfile/current_function.hpp +++ b/src/cllazyfile/current_function.hpp @@ -28,26 +28,18 @@ # define SC_CURRENT_FUNCTION __PRETTY_FUNCTION__ -#elif defined(__FUNCSIG__) +#elif defined(_MSC_VER) && _MSC_VER < 1900 -# define SC_CURRENT_FUNCTION __FUNCSIG__ +# define SC_CURRENT_FUNCTION __FUNCTION__ #elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) # define SC_CURRENT_FUNCTION __FUNCTION__ -#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) - -# define SC_CURRENT_FUNCTION __FUNC__ - -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +#else // STDC # define SC_CURRENT_FUNCTION __func__ -#else - -# define SC_CURRENT_FUNCTION "(unknown)" - #endif #endif // #ifndef CURRENT_FUNCTION_HPP_INCLUDED diff --git a/src/base/judy/src/judy.c b/src/cllazyfile/judy.c similarity index 94% rename from src/base/judy/src/judy.c rename to src/cllazyfile/judy.c index fb5fb5fed..f3bba2b7e 100644 --- a/src/base/judy/src/judy.c +++ b/src/cllazyfile/judy.c @@ -60,7 +60,7 @@ # endif #endif -#include "judy.h" +#include "cllazyfile/judy.h" #include #include @@ -193,7 +193,7 @@ void * judy_alloc( Judy * judy, unsigned int type ) { if( type >= JUDY_1 ) for( idx = type; idx++ < JUDY_max; ) - if( block = judy->reuse[idx] ) { + if( (block = judy->reuse[idx]) ) { judy->reuse[idx] = *block; while( idx-- > type ) { judy->reuse[idx] = block + JudySize[idx] / sizeof( void * ); @@ -366,7 +366,7 @@ unsigned int judy_key( Judy * judy, unsigned char * buff, unsigned int max ) { off = keysize; while( off-- && len < max ) - if( buff[len] = base[slot * keysize + off] ) { + if( (buff[len] = base[slot * keysize + off]) ) { len++; } else { break; @@ -495,7 +495,7 @@ JudySlot * judy_slot( Judy * judy, const unsigned char * buff, unsigned int max // is this a leaf? - if( !judy->depth && !( value & 0xFF ) || judy->depth && depth == judy->depth ) { + if( (!judy->depth && !( value & 0xFF )) || (judy->depth && depth == judy->depth) ) { return &node[-slot - 1]; } @@ -509,7 +509,7 @@ JudySlot * judy_slot( Judy * judy, const unsigned char * buff, unsigned int max table = ( JudySlot * )( next & JUDY_mask ); // outer radix if( judy->depth ) { - slot = ( src[depth] >> ( ( JUDY_key_size - ++off & JUDY_key_mask ) * 8 ) ) & 0xff; + slot = ( src[depth] >> ( (( JUDY_key_size - ++off) & JUDY_key_mask ) * 8 ) ) & 0xff; } else if( off < max ) { slot = buff[off++]; } else { @@ -531,12 +531,13 @@ JudySlot * judy_slot( Judy * judy, const unsigned char * buff, unsigned int max depth++; } - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) // leaf? + if( (!judy->depth && !slot) || (judy->depth && depth == judy->depth) ) { // leaf? if( table[slot & 0x0F] ) { // occupied? return &table[slot & 0x0F]; } else { return NULL; } + } next = table[slot & 0x0F]; continue; @@ -650,7 +651,7 @@ void judy_radix( Judy * judy, JudySlot * radix, unsigned char * old, int start, // is this slot a leaf? - if( !judy->depth && ( !key || !keysize ) || judy->depth && !keysize && depth == judy->depth ) { + if( (!judy->depth && ( !key || !keysize )) || (judy->depth && !keysize && depth == judy->depth) ) { table[key & 0x0F] = oldnode[-start - 1]; return; } @@ -763,7 +764,7 @@ JudySlot * judy_first( Judy * judy, JudySlot next, unsigned int off, unsigned in judy->stack[judy->level].slot = slot; #if BYTE_ORDER != BIG_ENDIAN - if( !judy->depth && !base[slot * keysize] || judy->depth && ++depth == judy->depth ) { + if( (!judy->depth && !base[slot * keysize]) || (judy->depth && ++depth == judy->depth) ) { return &node[-slot - 1]; } #else @@ -787,7 +788,7 @@ JudySlot * judy_first( Judy * judy, JudySlot next, unsigned int off, unsigned in if( ( inner = ( JudySlot * )( table[slot >> 4] & JUDY_mask ) ) ) { if( ( next = inner[slot & 0x0F] ) ) { judy->stack[judy->level].slot = slot; - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) { + if( (!judy->depth && !slot) || (judy->depth && depth == judy->depth) ) { return &inner[slot & 0x0F]; } else { break; @@ -848,9 +849,9 @@ JudySlot * judy_last( Judy * judy, JudySlot next, unsigned int off, unsigned int judy->stack[judy->level].slot = --slot; #if BYTE_ORDER != BIG_ENDIAN - if( !judy->depth && !base[slot * keysize] || judy->depth && ++depth == judy->depth ) + if( (!judy->depth && !base[slot * keysize]) || (judy->depth && ++depth == judy->depth) ) #else - if( !judy->depth && !base[slot * keysize + keysize - 1] || judy->depth && ++depth == judy->depth ) + if( (!judy->depth && !base[slot * keysize + keysize - 1]) || judy->depth && ++depth == judy->depth ) #endif return &node[-slot - 1]; @@ -870,12 +871,13 @@ JudySlot * judy_last( Judy * judy, JudySlot next, unsigned int off, unsigned int for( slot = 256; slot--; ) { judy->stack[judy->level].slot = slot; if( ( inner = ( JudySlot * )( table[slot >> 4] & JUDY_mask ) ) ) { - if( ( next = inner[slot & 0x0F] ) ) - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) { + if( ( next = inner[slot & 0x0F] ) ) { + if( (!judy->depth && !slot) || (judy->depth && depth == judy->depth) ) { return &inner[0]; } else { break; } + } } else { slot &= 0xF0; } @@ -942,11 +944,11 @@ JudySlot * judy_nxt( Judy * judy ) { cnt = size / ( sizeof( JudySlot ) + keysize ); node = ( JudySlot * )( ( next & JUDY_mask ) + size ); base = ( unsigned char * )( next & JUDY_mask ); - if( ++slot < cnt ) + if( ++slot < cnt ) { #if BYTE_ORDER != BIG_ENDIAN - if( !judy->depth && !base[slot * keysize] || judy->depth && ++depth == judy->depth ) + if( (!judy->depth && !base[slot * keysize]) || (judy->depth && ++depth == judy->depth) ) #else - if( !judy->depth && !base[slot * keysize + keysize - 1] || judy->depth && ++depth == judy->depth ) + if( (!judy->depth && !base[slot * keysize + keysize - 1]) || (judy->depth && ++depth == judy->depth) ) #endif { judy->stack[judy->level].slot = slot; @@ -955,6 +957,7 @@ JudySlot * judy_nxt( Judy * judy ) { judy->stack[judy->level].slot = slot; return judy_first( judy, node[-slot - 1], ( off | JUDY_key_mask ) + 1, depth ); } + } judy->level--; continue; @@ -1033,9 +1036,9 @@ JudySlot * judy_prv( Judy * judy ) { keysize = JUDY_key_size - ( off & JUDY_key_mask ); #if BYTE_ORDER != BIG_ENDIAN - if( !judy->depth && !base[( slot - 1 ) * keysize] || judy->depth && ++depth == judy->depth ) + if( (!judy->depth && !base[( slot - 1 ) * keysize]) || (judy->depth && ++depth == judy->depth) ) #else - if( !judy->depth && !base[( slot - 1 ) * keysize + keysize - 1] || judy->depth && ++depth == judy->depth ) + if( (!judy->depth && !base[( slot - 1 ) * keysize + keysize - 1]) || (judy->depth && ++depth == judy->depth) ) #endif return &node[-slot]; return judy_last( judy, node[-slot], ( off | JUDY_key_mask ) + 1, depth ); @@ -1051,12 +1054,13 @@ JudySlot * judy_prv( Judy * judy ) { while( slot-- ) { judy->stack[judy->level].slot--; if( ( inner = ( JudySlot * )( table[slot >> 4] & JUDY_mask ) ) ) - if( inner[slot & 0x0F] ) - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) { + if( inner[slot & 0x0F] ) { + if( (!judy->depth && !slot) || (judy->depth && depth == judy->depth) ) { return &inner[0]; } else { return judy_last( judy, inner[slot & 0x0F], off + 1, depth ); } + } } judy->level--; @@ -1076,7 +1080,7 @@ JudySlot * judy_prv( Judy * judy ) { // returning previous entry. JudySlot * judy_del( Judy * judy ) { - int slot, off, size, type, high; + int slot, off, size, type; JudySlot * table, *inner; JudySlot next, *node; int keysize, cnt; @@ -1129,7 +1133,6 @@ JudySlot * judy_del( Judy * judy ) { table = ( JudySlot * )( next & JUDY_mask ); inner = ( JudySlot * )( table[slot >> 4] & JUDY_mask ); inner[slot & 0x0F] = 0; - high = slot & 0xF0; for( cnt = 16; cnt--; ) if( inner[cnt] ) { @@ -1291,7 +1294,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max // is this a leaf? - if( !judy->depth && !( value & 0xFF ) || judy->depth && depth == judy->depth ) { + if( (!judy->depth && !( value & 0xFF )) || (judy->depth && depth == judy->depth) ) { #ifdef ASKITIS if( *next ) { Found++; @@ -1327,7 +1330,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max node[-slot - 1] = 0; // set new tree ptr/cell next = &node[-slot - 1]; - if( !judy->depth && !( value & 0xFF ) || judy->depth && depth == judy->depth ) { + if( (!judy->depth && !( value & 0xFF )) || (judy->depth && depth == judy->depth) ) { #ifdef ASKITIS if( *next ) { Found++; @@ -1344,7 +1347,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max if( size < JudySize[JUDY_max] ) { next = judy_promote( judy, next, slot + 1, value, keysize ); - if( !judy->depth && !( value & 0xFF ) || judy->depth && depth == judy->depth ) { + if( (!judy->depth && !( value & 0xFF )) || (judy->depth && depth == judy->depth) ) { #ifdef ASKITIS if( *next ) { Found++; @@ -1375,7 +1378,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max table = ( JudySlot * )( *next & JUDY_mask ); // outer radix if( judy->depth ) { - slot = ( src[depth] >> ( ( JUDY_key_size - ++off & JUDY_key_mask ) * 8 ) ) & 0xff; + slot = ( src[depth] >> ( ( (JUDY_key_size - ++off) & JUDY_key_mask ) * 8 ) ) & 0xff; } else if( off < max ) { slot = buff[off++]; } else { @@ -1399,7 +1402,7 @@ JudySlot * judy_cell( Judy * judy, const unsigned char * buff, unsigned int max #endif next = &table[slot & 0x0F]; - if( !judy->depth && !slot || judy->depth && depth == judy->depth ) { // leaf? + if( (!judy->depth && !slot) || (judy->depth && depth == judy->depth) ) { // leaf? #ifdef ASKITIS if( *next ) { Found++; diff --git a/src/cllazyfile/lazyDataSectionReader.cc b/src/cllazyfile/lazyDataSectionReader.cc index 4b1bc1785..6de006fe4 100644 --- a/src/cllazyfile/lazyDataSectionReader.cc +++ b/src/cllazyfile/lazyDataSectionReader.cc @@ -1,6 +1,6 @@ -#include "lazyDataSectionReader.h" -#include "lazyFileReader.h" -#include "lazyInstMgr.h" +#include "cllazyfile/lazyDataSectionReader.h" +#include "cllazyfile/lazyFileReader.h" +#include "cllazyfile/lazyInstMgr.h" #include lazyDataSectionReader::lazyDataSectionReader( lazyFileReader * parent, std::ifstream & file, diff --git a/src/cllazyfile/lazyFileReader.cc b/src/cllazyfile/lazyFileReader.cc index b31a6dfd3..fed35c6f5 100644 --- a/src/cllazyfile/lazyFileReader.cc +++ b/src/cllazyfile/lazyFileReader.cc @@ -1,10 +1,10 @@ #include -#include "lazyFileReader.h" -#include "lazyDataSectionReader.h" -#include "headerSectionReader.h" -#include "lazyInstMgr.h" +#include "cllazyfile/lazyFileReader.h" +#include "cllazyfile/lazyDataSectionReader.h" +#include "cllazyfile/headerSectionReader.h" +#include "cllazyfile/lazyInstMgr.h" void lazyFileReader::initP21() { _header = new p21HeaderSectionReader( this, _file, 0, -1 ); @@ -50,7 +50,7 @@ instancesLoaded_t * lazyFileReader::getHeaderInstances() { } lazyFileReader::lazyFileReader( std::string fname, lazyInstMgr * i, fileID fid ): _fileName( fname ), _parent( i ), _fileID( fid ) { - _file.open( _fileName.c_str() ); + _file.open( _fileName.c_str(), std::ios::binary ); _file.imbue( std::locale::classic() ); _file.unsetf( std::ios_base::skipws ); assert( _file.is_open() && _file.good() ); diff --git a/src/cllazyfile/lazyInstMgr.cc b/src/cllazyfile/lazyInstMgr.cc index 7ce253ee9..65f3e7558 100644 --- a/src/cllazyfile/lazyInstMgr.cc +++ b/src/cllazyfile/lazyInstMgr.cc @@ -1,12 +1,12 @@ -#include "lazyTypes.h" -#include "lazyInstMgr.h" -#include "Registry.h" -#include -#include "SdaiSchemaInit.h" -#include "instMgrHelper.h" +#include "cllazyfile/lazyTypes.h" +#include "cllazyfile/lazyInstMgr.h" +#include "clstepcore/Registry.h" +#include "clstepcore/SubSuperIterators.h" +#include "cleditor/SdaiSchemaInit.h" +#include "cllazyfile/instMgrHelper.h" #include "lazyRefs.h" -#include "sdaiApplication_instance.h" +#include "clstepcore/sdaiApplication_instance.h" lazyInstMgr::lazyInstMgr() { _headerRegistry = new Registry( HeaderSchemaInit ); diff --git a/src/cllazyfile/lazyP21DataSectionReader.cc b/src/cllazyfile/lazyP21DataSectionReader.cc index 9e9df2070..0716f5c5f 100644 --- a/src/cllazyfile/lazyP21DataSectionReader.cc +++ b/src/cllazyfile/lazyP21DataSectionReader.cc @@ -1,7 +1,7 @@ #include #include -#include "lazyP21DataSectionReader.h" -#include "lazyInstMgr.h" +#include "cllazyfile/lazyP21DataSectionReader.h" +#include "cllazyfile/lazyInstMgr.h" lazyP21DataSectionReader::lazyP21DataSectionReader( lazyFileReader * parent, std::ifstream & file, std::streampos start, sectionID sid ): @@ -49,6 +49,7 @@ const namedLazyInstance lazyP21DataSectionReader::nextInstance() { namedLazyInstance i; i.refs = 0; + i.loc.section = 0; i.loc.begin = _file.tellg(); i.loc.instance = readInstanceNumber(); if( ( _file.good() ) && ( i.loc.instance > 0 ) ) { diff --git a/src/cllazyfile/lazyRefs.h b/src/cllazyfile/lazyRefs.h index f94f41e7a..b8daff295 100644 --- a/src/cllazyfile/lazyRefs.h +++ b/src/cllazyfile/lazyRefs.h @@ -7,12 +7,12 @@ #include #include "sc_export.h" -#include "lazyTypes.h" -#include "lazyInstMgr.h" -#include "ExpDict.h" -#include "SubSuperIterators.h" -#include -#include +#include "cllazyfile/lazyTypes.h" +#include "cllazyfile/lazyInstMgr.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/SubSuperIterators.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/STEPaggregate.h" #ifdef _WIN32 #define strcasecmp _strcmpi @@ -48,7 +48,7 @@ class SDAI_Application_instance; * BENEFIT: no need to write lazyInstMgr::getTypeStr() (however, it might be necessary in the future regardless) */ -//TODO screen out intances that appear to be possible inverse refs but aren't actually +//TODO screen out instances that appear to be possible inverse refs but aren't actually // note - doing this well will require major changes, since each inst automatically loads every instance that it references //TODO what about complex instances? scanning each on disk could be a bitch; should the compositional types be scanned during lazy loading? @@ -60,12 +60,19 @@ class SC_LAZYFILE_EXPORT lazyRefs { typedef std::set< const Inverse_attribute * > iaList_t; typedef judyLArray< instanceID, std::string * > refMap_t; typedef std::set< const EntityDescriptor * > edList_t; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif iaList_t _iaList; lazyInstMgr * _lim; instanceID _id; refMap_t _refMap; referentInstances_t _referentInstances; SDAI_Application_instance * _inst; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif void checkAnInvAttr( const Inverse_attribute * ia ) { const EntityDescriptor * ed; @@ -108,9 +115,9 @@ class SC_LAZYFILE_EXPORT lazyRefs { if( !ai ) { ias.i = rinst; _inst->setInvAttr( ia, ias ); - } else if( ai->GetFileId() != (int)inst ) { - std::cerr << "ERROR: two instances (" << rinst << ", #" << rinst->GetFileId() << "=" << rinst->getEDesc()->Name(); - std::cerr << " and " << ai << ", #" << ai->GetFileId() <<"=" << ai->getEDesc()->Name() << ") refer to inst "; + } else if( ai->GetFileId() != ( int )inst ) { + std::cerr << "ERROR: two instances (" << rinst << ", #" << rinst->GetFileId() << "=" << rinst->eDesc->Name(); + std::cerr << " and " << ai << ", #" << ai->GetFileId() << "=" << ai->eDesc->Name() << ") refer to inst "; std::cerr << _inst->GetFileId() << ", but its inverse attribute is not an aggregation type!" << std::endl; // TODO _error->GreaterSeverity( SEVERITY_INPUT_ERROR ); } @@ -177,7 +184,7 @@ class SC_LAZYFILE_EXPORT lazyRefs { } ++iai; } - std::cerr << "Error! inverse attr " << ia->Name() << " (" << ia << ") not found in iAMap for entity " << inst->getEDesc()->Name() << std::endl; + std::cerr << "Error! inverse attr " << ia->Name() << " (" << ia << ") not found in iAMap for entity " << inst->eDesc->Name() << std::endl; abort(); iAstruct nil = {nullptr}; return nil; @@ -272,7 +279,7 @@ class SC_LAZYFILE_EXPORT lazyRefs { // 1. find inverse attrs with recursion - getInverseAttrs( ai->getEDesc(), _iaList ); + getInverseAttrs( ai->eDesc, _iaList ); //2. find reverse refs, map id to type (stop if there are no inverse attrs or no refs) if( _iaList.size() == 0 || !mapRefsToTypes() ) { diff --git a/src/cllazyfile/lazy_test.cc b/src/cllazyfile/lazy_test.cc index 87838e467..d5ce6081a 100644 --- a/src/cllazyfile/lazy_test.cc +++ b/src/cllazyfile/lazy_test.cc @@ -1,8 +1,7 @@ -#include "lazyInstMgr.h" -#include -#include "SdaiSchemaInit.h" -#include "sc_memmgr.h" -#include +#include "cllazyfile/lazyInstMgr.h" +#include "./sc_benchmark.h" +#include "cleditor/SdaiSchemaInit.h" +#include "config.h" #ifndef NO_REGISTRY # include "schema.h" @@ -111,14 +110,14 @@ void dumpComplexInst( STEPcomplex * c ) { STEPcomplex * complex = c->head; while( complex ) { if( complex->IsComplex() ) { - std::cout << "Complex component " << complex->getEDesc()->Name() << " at depth " << depth << " with attr list size "; + std::cout << "Complex component " << complex->eDesc->Name() << " at depth " << depth << " with attr list size "; std::cout << complex->_attr_data_list.size() << std::endl; // dumpComplexInst( complex, depth + 1 ); } else { //probably won't ever get here... SDAI_Application_instance * ai = dynamic_cast< SDAI_Application_instance * >( complex ); if( ai ) { - std::cout << "non-complex component at depth " << depth << ", " << ai->getEDesc()->Name() << std::endl; + std::cout << "non-complex component at depth " << depth << ", " << ai->eDesc->Name() << std::endl; } else { std::cout << "unknown component at depth " << depth << ": " << complex << std::endl; } diff --git a/src/cllazyfile/p21HeaderSectionReader.cc b/src/cllazyfile/p21HeaderSectionReader.cc index bcb78ac83..037604fc4 100644 --- a/src/cllazyfile/p21HeaderSectionReader.cc +++ b/src/cllazyfile/p21HeaderSectionReader.cc @@ -1,11 +1,11 @@ #include #include -#include "p21HeaderSectionReader.h" -#include "headerSectionReader.h" -#include "sectionReader.h" -#include "lazyInstMgr.h" -#include "judyL2Array.h" +#include "cllazyfile/p21HeaderSectionReader.h" +#include "cllazyfile/headerSectionReader.h" +#include "cllazyfile/sectionReader.h" +#include "cllazyfile/lazyInstMgr.h" +#include "cllazyfile/judyL2Array.h" void p21HeaderSectionReader::findSectionStart() { @@ -33,6 +33,7 @@ const namedLazyInstance p21HeaderSectionReader::nextInstance() { namedLazyInstance i; static instanceID nextFreeInstance = 4; // 1-3 are reserved per 10303-21 + i.refs = 0; i.loc.begin = _file.tellg(); i.loc.section = _sectionID; skipWS(); diff --git a/src/base/sc_benchmark.cc b/src/cllazyfile/sc_benchmark.cc similarity index 98% rename from src/base/sc_benchmark.cc rename to src/cllazyfile/sc_benchmark.cc index cbf8ce98b..2f00cd5a4 100644 --- a/src/base/sc_benchmark.cc +++ b/src/cllazyfile/sc_benchmark.cc @@ -1,9 +1,8 @@ /// \file sc_benchmark.cc memory info, timers, etc for benchmarking -#include "sc_benchmark.h" -#include "sc_memmgr.h" +#include "./sc_benchmark.h" -#ifdef __WIN32__ +#ifdef _WIN32 #include #include #else @@ -49,7 +48,7 @@ benchVals getMemAndTime( ) { vals.sysMilliseconds = ( stime * 1000 ) / sysconf( _SC_CLK_TCK ); #elif defined(__APPLE__) // http://stackoverflow.com/a/1911863/382458 -#elif defined(__WIN32__) +#elif defined(_WIN32) // http://stackoverflow.com/a/282220/382458 and http://stackoverflow.com/a/64166/382458 PROCESS_MEMORY_COUNTERS MemoryCntrs; FILETIME CreationTime, ExitTime, KernelTime, UserTime; diff --git a/src/base/sc_benchmark.h b/src/cllazyfile/sc_benchmark.h similarity index 91% rename from src/base/sc_benchmark.h rename to src/cllazyfile/sc_benchmark.h index 4721b2ae7..5b77317c4 100644 --- a/src/base/sc_benchmark.h +++ b/src/cllazyfile/sc_benchmark.h @@ -2,14 +2,11 @@ #define SC_BENCHMARK_H /// \file sc_benchmark.h memory info, timers, etc for benchmarking -#include "sc_export.h" - #ifdef __cplusplus #include #include #include -#include "sc_memmgr.h" extern "C" { #endif @@ -23,7 +20,7 @@ extern "C" { * * not yet implemented for OSX or Windows. */ - SC_BASE_EXPORT benchVals getMemAndTime( ); + benchVals getMemAndTime( ); #ifdef __cplusplus } @@ -39,11 +36,18 @@ extern "C" { * depends on getMemAndTime() above - may not work on all platforms. */ -class SC_BASE_EXPORT benchmark { +class benchmark { protected: benchVals initialVals, laterVals; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif std::ostream & ostr; std::string descr; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif bool debug, stopped; public: benchmark( std::string description = "", bool debugMessages = true, std::ostream & o_stream = std::cout ); diff --git a/src/cllazyfile/sectionReader.cc b/src/cllazyfile/sectionReader.cc index bd3d9c23a..bfa8a2a12 100644 --- a/src/cllazyfile/sectionReader.cc +++ b/src/cllazyfile/sectionReader.cc @@ -5,18 +5,23 @@ #include #include #include +#include -#include "Registry.h" -#include "sc_strtoull.h" -#include "sdaiApplication_instance.h" -#include "read_func.h" -#include "SdaiSchemaInit.h" -#include "STEPcomplex.h" +#ifdef _WIN32 +# define strtoull _strtoui64 +# define ULLONG_MAX _UI64_MAX +#endif -#include "sectionReader.h" -#include "lazyFileReader.h" -#include "lazyInstMgr.h" -#include "lazyTypes.h" +#include "clstepcore/Registry.h" +#include "clstepcore/sdaiApplication_instance.h" +#include "clstepcore/read_func.h" +#include "cleditor/SdaiSchemaInit.h" +#include "clstepcore/STEPcomplex.h" + +#include "cllazyfile/sectionReader.h" +#include "cllazyfile/lazyFileReader.h" +#include "cllazyfile/lazyInstMgr.h" +#include "cllazyfile/lazyTypes.h" #include "current_function.hpp" @@ -26,11 +31,14 @@ sectionReader::sectionReader( lazyFileReader * parent, std::ifstream & file, std _error = new ErrorDescriptor(); } +sectionReader::~sectionReader() { + delete _error; +} std::streampos sectionReader::findNormalString( const std::string & str, bool semicolon ) { std::streampos found = -1, startPos = _file.tellg(), nextTry = startPos; int i = 0, l = str.length(); - char c; + int c; //i is reset every time a character doesn't match; if i == l, this means that we've found the entire string while( i < l || semicolon ) { @@ -47,7 +55,7 @@ std::streampos sectionReader::findNormalString( const std::string & str, bool se } if( c == '\'' ) { //push past string - _file.unget(); + _file.seekg( _file.tellg() - std::streampos(1) ); GetLiteralStr( _file, _lazyFile->getInstMgr()->getErrorDesc() ); } if( ( c == '/' ) && ( _file.peek() == '*' ) ) { @@ -84,7 +92,7 @@ std::streampos sectionReader::findNormalString( const std::string & str, bool se // returns pointer to the contents of a static std::string const char * sectionReader::getDelimitedKeyword( const char * delimiters ) { static std::string str; - char c; + int c; str.clear(); str.reserve( 100 ); skipWS(); @@ -114,7 +122,7 @@ const char * sectionReader::getDelimitedKeyword( const char * delimiters ) { /// be the opening parenthesis; otherwise, it is likely to fail. ///NOTE *must* check return value! std::streampos sectionReader::seekInstanceEnd( instanceRefs ** refs ) { - char c; + int c; int parenDepth = 0; while( c = _file.get(), _file.good() ) { switch( c ) { @@ -129,7 +137,7 @@ std::streampos sectionReader::seekInstanceEnd( instanceRefs ** refs ) { } break; case '\'': - _file.unget(); + _file.seekg( _file.tellg() - std::streampos(1) ); GetLiteralStr( _file, _lazyFile->getInstMgr()->getErrorDesc() ); break; case '=': @@ -155,7 +163,7 @@ std::streampos sectionReader::seekInstanceEnd( instanceRefs ** refs ) { if( _file.get() == ';' ) { return _file.tellg(); } else { - _file.unget(); + _file.seekg( _file.tellg() - std::streampos(1) ); } } default: @@ -176,7 +184,7 @@ void sectionReader::locateAllInstances() { } instanceID sectionReader::readInstanceNumber() { - char c; + int c; size_t digits = 0; instanceID id = 0; @@ -186,7 +194,7 @@ instanceID sectionReader::readInstanceNumber() { if( ( c == '/' ) && ( _file.peek() == '*' ) ) { findNormalString( "*/" ); } else { - _file.unget(); + _file.seekg( _file.tellg() - std::streampos(1) ); } skipWS(); c = _file.get(); @@ -206,11 +214,11 @@ instanceID sectionReader::readInstanceNumber() { do { c = _file.get(); if( isdigit( c ) ) { - buffer[ digits ] = c; //copy the charcter into the buffer + buffer[ digits ] = c; //copy the character into the buffer digits++; } else { - _file.unget(); + _file.seekg( _file.tellg() - std::streampos(1) ); break; } @@ -221,7 +229,7 @@ instanceID sectionReader::readInstanceNumber() { _error->UserMsg( "A very large instance ID encountered" ); _error->DetailMsg( errorMsg.str() ); - delete buffer; + delete[] buffer; return 0; } @@ -251,7 +259,7 @@ instanceID sectionReader::readInstanceNumber() { */ SDAI_Application_instance * sectionReader::getRealInstance( const Registry * reg, long int begin, instanceID instance, const std::string & typeName, const std::string & schName, bool header ) { - char c; + int c; const char * tName = 0, * sName = 0; //these are necessary since typeName and schName are const std::string comment; Severity sev = SEVERITY_NULL; @@ -306,10 +314,10 @@ SDAI_Application_instance * sectionReader::getRealInstance( const Registry * reg if( !comment.empty() ) { inst->AddP21Comment( comment ); } - assert( inst->getEDesc() ); + assert( inst->eDesc ); _file.seekg( begin ); findNormalString( "(" ); - _file.unget(); + _file.seekg( _file.tellg() - std::streampos(1) ); sev = inst->STEPread( instance, 0, _lazyFile->getInstMgr()->getAdapter(), _file, sName, true, false ); //TODO do something with 'sev' inst->InitIAttrs(); diff --git a/src/clstepcore/CMakeLists.txt b/src/clstepcore/CMakeLists.txt index c18257986..e31f8ad8e 100644 --- a/src/clstepcore/CMakeLists.txt +++ b/src/clstepcore/CMakeLists.txt @@ -1,5 +1,4 @@ - -set(LIBSTEPCORE_SRCS +set(CORE_SRCS aggrTypeDescriptor.cc attrDescriptor.cc attrDescriptorList.cc @@ -62,79 +61,23 @@ set(LIBSTEPCORE_SRCS whereRule.cc ) -set(SC_CLSTEPCORE_HDRS - aggrTypeDescriptor.h - attrDescriptor.h - attrDescriptorList.h - baseType.h - complexSupport.h - create_Aggr.h - derivedAttribute.h - dictSchema.h - dictdefs.h - dictionaryInstance.h - dispnode.h - dispnodelist.h - entityDescriptor.h - entityDescriptorList.h - enumTypeDescriptor.h - ExpDict.h - explicitItemId.h - globalRule.h - implicitItemId.h - instmgr.h - interfaceSpec.h - interfacedItem.h - inverseAttribute.h - inverseAttributeList.h - mgrnode.h - mgrnodearray.h - mgrnodelist.h - needFunc.h - read_func.h - realTypeDescriptor.h - Registry.h - schRename.h - sdai.h - sdaiApplication_instance.h - sdaiSelect.h - selectTypeDescriptor.h - SingleLinkList.h - STEPaggregate.h - STEPaggrBinary.h - STEPaggrEntity.h - STEPaggrEnum.h - STEPaggrGeneric.h - STEPaggrInt.h - STEPaggrReal.h - STEPaggrSelect.h - STEPaggrString.h - STEPattribute.h - STEPattributeList.h - STEPcomplex.h - STEPinvAttrList.h - STEPundefined.h - stringTypeDescriptor.h - SubSuperIterators.h - typeDescriptor.h - typeDescriptorList.h - typeOrRuleVar.h - uniquenessRule.h - whereRule.h -) - 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_SOURCE_DIR}/include/stepcode ) -SC_ADDLIB(stepcore "${LIBSTEPCORE_SRCS}" "steputils;stepdai;base") +set(_libdeps steputils stepdai) + +if(BUILD_SHARED_LIBS) + SC_ADDLIB(stepcore SHARED SOURCES ${CORE_SRCS} LINK_LIBRARIES ${_libdeps}) + if(WIN32) + target_compile_definitions(stepcore PRIVATE SC_CORE_DLL_EXPORTS) + endif() +endif() -install(FILES ${SC_CLSTEPCORE_HDRS} - DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/clstepcore) +if(BUILD_STATIC_LIBS) + SC_ADDLIB(stepcore-static STATIC SOURCES ${CORE_SRCS} LINK_LIBRARIES $-static) +endif() if(SC_ENABLE_TESTING) add_subdirectory(test) diff --git a/src/clstepcore/Registry.cc b/src/clstepcore/Registry.cc index 6bbd3eaff..9eeb975e0 100644 --- a/src/clstepcore/Registry.cc +++ b/src/clstepcore/Registry.cc @@ -9,9 +9,8 @@ * and is not subject to copyright. */ -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/Registry.h" /* these may be shared between multiple Registry instances, so don't create/destroy in Registry ctor/dtor * Name, FundamentalType, Originating Schema, Description */ @@ -79,7 +78,7 @@ void Registry::DeleteContents() { const EntityDescriptor * Registry::FindEntity( const char * e, const char * schNm, int check_case ) const { const EntityDescriptor * entd; const SchRename * altlist; - char schformat[BUFSIZ], altName[BUFSIZ]; + char schformat[BUFSIZ+1], altName[BUFSIZ+1]; if( check_case ) { entd = ( EntityDescriptor * )SC_HASHfind( primordialSwamp, ( char * )e ); @@ -235,13 +234,13 @@ void Registry::RemoveType( const char * n ) { */ void Registry::RemoveClones( const EntityDescriptor & e ) { const SchRename * alts = e.AltNameList(); - struct Element * tmp; while( alts ) { - tmp = new Element; + struct Element * tmp = new Element; tmp->key = ( char * ) alts->objName(); SC_HASHsearch( primordialSwamp, tmp, HASH_DELETE ); alts = alts->next; + delete tmp; } } @@ -260,7 +259,7 @@ SDAI_Application_instance * Registry::ObjCreate( const char * nm, const char * s se->Error().severity( SEVERITY_WARNING ); se->Error().UserMsg( "ENTITY requires external mapping" ); } - se->setEDesc( entd ); + se->eDesc = entd; return se; } else { return ENTITY_NULL; diff --git a/src/clstepcore/STEPaggrBinary.cc b/src/clstepcore/STEPaggrBinary.cc index fd7302748..f1170926c 100644 --- a/src/clstepcore/STEPaggrBinary.cc +++ b/src/clstepcore/STEPaggrBinary.cc @@ -1,4 +1,4 @@ -#include "STEPaggrBinary.h" +#include "clstepcore/STEPaggrBinary.h" #include /** \file STEPaggrBinary.cc diff --git a/src/clstepcore/STEPaggrEntity.cc b/src/clstepcore/STEPaggrEntity.cc index bda8f6db5..02bfa3fb2 100644 --- a/src/clstepcore/STEPaggrEntity.cc +++ b/src/clstepcore/STEPaggrEntity.cc @@ -1,6 +1,6 @@ -#include "STEPaggrEntity.h" -#include "STEPattribute.h" -#include "typeDescriptor.h" +#include "clstepcore/STEPaggrEntity.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/typeDescriptor.h" #include /** \file STEPaggrEntity.cc @@ -21,9 +21,10 @@ Severity EntityAggregate::ReadValue( istream & in, ErrorDescriptor * err, int addFileId, int assignVal, int exchangeFileFormat, const char * ) { ErrorDescriptor errdesc; - char errmsg[BUFSIZ]; + char errmsg[BUFSIZ+1]; int value_cnt = 0; std::string buf; + bool free_item = false; if( assignVal ) { Empty(); // read new values and discard existing ones @@ -67,6 +68,7 @@ Severity EntityAggregate::ReadValue( istream & in, ErrorDescriptor * err, // It is used to read the values else if( !assignVal ) { item = new EntityNode(); + free_item = true; } while( in.good() && ( c != ')' ) ) { @@ -114,8 +116,12 @@ Severity EntityAggregate::ReadValue( istream & in, ErrorDescriptor * err, } else { // expectation for end paren delim has not been met err->GreaterSeverity( SEVERITY_INPUT_ERROR ); err->AppendToUserMsg( "Missing close paren for aggregate value" ); + if (free_item) + delete item; return SEVERITY_INPUT_ERROR; } + if (free_item) + delete item; return err->severity(); } diff --git a/src/clstepcore/STEPaggrEnum.cc b/src/clstepcore/STEPaggrEnum.cc index 41b77aa21..01ac21e4a 100644 --- a/src/clstepcore/STEPaggrEnum.cc +++ b/src/clstepcore/STEPaggrEnum.cc @@ -1,4 +1,4 @@ -#include "STEPaggrEnum.h" +#include "clstepcore/STEPaggrEnum.h" #include /** \file StepaggrEnum.cc diff --git a/src/clstepcore/STEPaggrGeneric.cc b/src/clstepcore/STEPaggrGeneric.cc index 899d6c656..5db812b27 100644 --- a/src/clstepcore/STEPaggrGeneric.cc +++ b/src/clstepcore/STEPaggrGeneric.cc @@ -1,4 +1,4 @@ -#include "STEPaggrGeneric.h" +#include "clstepcore/STEPaggrGeneric.h" #include /** \file STEPaggrGeneric.cc diff --git a/src/clstepcore/STEPaggrInt.cc b/src/clstepcore/STEPaggrInt.cc index 2e61a1504..936ab36d8 100644 --- a/src/clstepcore/STEPaggrInt.cc +++ b/src/clstepcore/STEPaggrInt.cc @@ -1,4 +1,4 @@ -#include "STEPaggrInt.h" +#include "clstepcore/STEPaggrInt.h" IntAggregate::IntAggregate() { @@ -94,7 +94,7 @@ const char * IntNode::asStr( std::string & s ) { } const char * IntNode::STEPwrite( std::string & s, const char * ) { - char tmp[BUFSIZ]; + char tmp[BUFSIZ+1]; if( value != S_INT_NULL ) { sprintf( tmp, "%ld", value ); s = tmp; diff --git a/src/clstepcore/STEPaggrReal.cc b/src/clstepcore/STEPaggrReal.cc index 7d05c1333..96ae53406 100644 --- a/src/clstepcore/STEPaggrReal.cc +++ b/src/clstepcore/STEPaggrReal.cc @@ -1,4 +1,4 @@ -#include "STEPaggrReal.h" +#include "clstepcore/STEPaggrReal.h" /** \file STEPaggrReal.cc * implementation of classes RealAggregate and RealNode diff --git a/src/clstepcore/STEPaggrSelect.cc b/src/clstepcore/STEPaggrSelect.cc index 02970479c..73fe97176 100644 --- a/src/clstepcore/STEPaggrSelect.cc +++ b/src/clstepcore/STEPaggrSelect.cc @@ -1,5 +1,5 @@ -#include "STEPaggrSelect.h" -#include "typeDescriptor.h" +#include "clstepcore/STEPaggrSelect.h" +#include "clstepcore/typeDescriptor.h" #include /** \file STEPaggrSelect.cc @@ -19,7 +19,7 @@ Severity SelectAggregate::ReadValue( istream & in, ErrorDescriptor * err, int addFileId, int assignVal, int exchangeFileFormat, const char * currSch ) { ErrorDescriptor errdesc; - char errmsg[BUFSIZ]; + char errmsg[BUFSIZ+1]; int value_cnt = 0; std::string buf; diff --git a/src/clstepcore/STEPaggrString.cc b/src/clstepcore/STEPaggrString.cc index fd9285ad3..1aaf752e1 100644 --- a/src/clstepcore/STEPaggrString.cc +++ b/src/clstepcore/STEPaggrString.cc @@ -1,4 +1,4 @@ -#include "STEPaggrString.h" +#include "clstepcore/STEPaggrString.h" #include /** \file STEPaggrString.cc diff --git a/src/clstepcore/STEPaggregate.cc b/src/clstepcore/STEPaggregate.cc index 65af0927a..4336aa6f6 100644 --- a/src/clstepcore/STEPaggregate.cc +++ b/src/clstepcore/STEPaggregate.cc @@ -12,12 +12,11 @@ #include -#include -#include -#include -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/read_func.h" +#include "clstepcore/STEPaggregate.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/instmgr.h" +#include "clstepcore/ExpDict.h" /** @@ -106,7 +105,7 @@ Severity STEPaggregate::ReadValue( istream & in, ErrorDescriptor * err, (void) addFileId; //not used in ReadValue() for this class ErrorDescriptor errdesc; - char errmsg[BUFSIZ]; + char errmsg[BUFSIZ+1]; int value_cnt = 0; std::string buf; @@ -355,7 +354,7 @@ const char * STEPnode::asStr( std::string & s ) { * cause e.g. type X may be defined in schema A, and may be USEd in schema * B and renamed to Y (i.e., "USE from A (X as Y)"). Thus, if currSch = B, * Y will have to be written out rather than X. Actually, this concern - * only applies for SelectNode. To accomodate those cases, all the signa- + * only applies for SelectNode. To accommodate those cases, all the signa- * tures of STEPwrite(std::string) contain currSch. (As an additional note, * 2D aggregates should make use of currSch in case they are 2D aggrs of * selects. But since currently (3/27/97) the SCL handles 2D+ aggrs using diff --git a/src/clstepcore/STEPattribute.cc b/src/clstepcore/STEPattribute.cc index 251beb445..ff07d55b7 100644 --- a/src/clstepcore/STEPattribute.cc +++ b/src/clstepcore/STEPattribute.cc @@ -12,14 +12,13 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/read_func.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/instmgr.h" +#include "clstepcore/STEPundefined.h" +#include "clstepcore/STEPaggregate.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/sdai.h" // REAL_NUM_PRECISION is defined in STEPattribute.h, and is also used // in aggregate real handling (STEPaggregate.cc) -- IMS 6 Jun 95 @@ -382,6 +381,100 @@ Severity STEPattribute::STEPread( istream & in, InstMgrBase * instances, int add } } +/*****************************************************************//** + ** \fn asStr + ** \param currSch - used for select type writes. See commenting in SDAI_Select::STEPwrite(). + ** \returns the value of the attribute + ** Status: complete 3/91 + *********************************************************************/ +const char * STEPattribute::asStr( std::string & str, const char * currSch ) const { + ostringstream ss; + + str.clear(); + + // The attribute has been derived by a subtype's attribute + if( IsDerived() ) { + str = "*"; + return const_cast( str.c_str() ); + } + + // The attribute has been redefined by the attribute pointed + // to by _redefAttr so write the redefined value. + if( _redefAttr ) { + return _redefAttr->asStr( str, currSch ); + } + + if( is_null() ) { + str = ""; + return const_cast( str.c_str() ); + } + + switch( NonRefType() ) { + case INTEGER_TYPE: + ss << *( ptr.i ); + str += ss.str(); + break; + + case NUMBER_TYPE: + case REAL_TYPE: + + ss.precision( ( int ) Real_Num_Precision ); + ss << *( ptr.r ); + str += ss.str(); + break; + + case ENTITY_TYPE: + // print instance id only if not empty pointer + // and has value assigned + if( ( *( ptr.c ) == S_ENTITY_NULL ) || ( *( ptr.c ) == 0 ) ) { + break; + } else { + ( *( ptr.c ) )->STEPwrite_reference( str ); + } + break; + + case BINARY_TYPE: + if( !( ( ptr.b )->empty() ) ) { + ( ptr.b ) -> STEPwrite( str ); + } + break; + + case STRING_TYPE: + if( !( ( ptr.S )->empty() ) ) { + return ( ptr.S ) -> asStr( str ); + } + break; + + case AGGREGATE_TYPE: + case ARRAY_TYPE: // DAS + case BAG_TYPE: // DAS + case SET_TYPE: // DAS + case LIST_TYPE: // DAS + return ptr.a->asStr( str ) ; + + case ENUM_TYPE: + case BOOLEAN_TYPE: + case LOGICAL_TYPE: + return ptr.e -> asStr( str ); + + case SELECT_TYPE: + ptr.sh -> STEPwrite( str, currSch ); + return const_cast( str.c_str() ); + + case REFERENCE_TYPE: + case GENERIC_TYPE: + cerr << "Internal error: " << __FILE__ << __LINE__ + << "\n" << _POC_ "\n"; + return 0; + + case UNKNOWN_TYPE: + default: + return ( ptr.u -> asStr( str ) ); + } + return const_cast( str.c_str() ); +} + + /*****************************************************************//** ** \fn asStr ** \param currSch - used for select type writes. See commenting in SDAI_Select::STEPwrite(). @@ -1169,20 +1262,20 @@ ostream & operator<< ( ostream & out, STEPattribute & a ) { * value. ******************************************************************/ void STEPattribute::AddErrorInfo() { - char errStr[BUFSIZ]; + char errStr[BUFSIZ+1]; errStr[0] = '\0'; if( SEVERITY_INPUT_ERROR < _error.severity() && _error.severity() < SEVERITY_NULL ) { sprintf( errStr, " Warning: ATTRIBUTE '%s : %s : %d' - ", - Name(), TypeName(), Type() ); + Name(), TypeName().c_str(), Type() ); _error.PrependToDetailMsg( errStr ); } else if( _error.severity() == SEVERITY_INPUT_ERROR ) { sprintf( errStr, " Error: ATTRIBUTE '%s : %s : %d' - ", - Name(), TypeName(), Type() ); + Name(), TypeName().c_str(), Type() ); _error.PrependToDetailMsg( errStr ); } else if( _error.severity() <= SEVERITY_BUG ) { sprintf( errStr, " BUG: ATTRIBUTE '%s : %s : %d' - ", - Name(), TypeName(), Type() ); + Name(), TypeName().c_str(), Type() ); _error.PrependToDetailMsg( errStr ); } } @@ -1199,7 +1292,7 @@ char STEPattribute::SkipBadAttr( istream & in, char * StopChars ) { // read bad data until end of this attribute or entity. char * foundCh = 0; char c = '\0'; - char errStr[BUFSIZ]; + char errStr[BUFSIZ+1]; errStr[0] = '\0'; _error.GreaterSeverity( SEVERITY_WARNING ); @@ -1210,12 +1303,12 @@ char STEPattribute::SkipBadAttr( istream & in, char * StopChars ) { if( in.eof() ) { _error.GreaterSeverity( SEVERITY_INPUT_ERROR ); sprintf( errStr, " Error: attribute '%s : %s : %d' - %s.\n", - Name(), TypeName(), Type(), + Name(), TypeName().c_str(), Type(), "Unexpected EOF when skipping bad attr value" ); _error.AppendToDetailMsg( errStr ); } else { sprintf( errStr, " Error: attribute '%s : %s : %d' - %s.\n", - Name(), TypeName(), Type(), "Invalid value" ); + Name(), TypeName().c_str(), Type(), "Invalid value" ); _error.AppendToDetailMsg( errStr ); } in.putback( c ); @@ -1353,6 +1446,7 @@ STEPattribute::~STEPattribute() { delete ( SDAI_BOOLEAN * ) ptr.e; ptr.e = 0; } + break; case LOGICAL_TYPE: if( ptr.e ) { delete ( SDAI_LOGICAL * ) ptr.e; @@ -1370,11 +1464,11 @@ const char * STEPattribute::Name() const { return aDesc->Name(); } -const char * STEPattribute::TypeName() const { +std::string STEPattribute::TypeName() const { if( _redefAttr ) { return _redefAttr->TypeName(); } - return aDesc->TypeName().c_str(); + return aDesc->TypeName(); } BASE_TYPE STEPattribute::Type() const { diff --git a/src/clstepcore/STEPattributeList.cc b/src/clstepcore/STEPattributeList.cc index 7774321b2..2993dd275 100644 --- a/src/clstepcore/STEPattributeList.cc +++ b/src/clstepcore/STEPattributeList.cc @@ -10,9 +10,8 @@ * and is not subject to copyright. */ -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/STEPattributeList.h" +#include "clstepcore/STEPattribute.h" AttrListNode::AttrListNode( STEPattribute * a ) { attr = a; diff --git a/src/clstepcore/STEPcomplex.cc b/src/clstepcore/STEPcomplex.cc index 5daf31ab7..9451d6df6 100644 --- a/src/clstepcore/STEPcomplex.cc +++ b/src/clstepcore/STEPcomplex.cc @@ -1,12 +1,11 @@ #include -#include -#include -#include -#include +#include "clstepcore/STEPcomplex.h" +#include "clstepcore/complexSupport.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/STEPaggregate.h" #include -#include "sc_memmgr.h" extern const char * ReadStdKeyword( istream & in, std::string & buf, int skipInitWS ); @@ -20,7 +19,7 @@ STEPcomplex::STEPcomplex( Registry * registry, int fileid ) STEPcomplex::STEPcomplex( Registry * registry, const std::string ** names, int fileid, const char * schnm ) : SDAI_Application_instance( fileid, true ), sc( 0 ), _registry( registry ), visited( 0 ) { - char * nms[BUFSIZ]; + char * nms[BUFSIZ+1]; int j, k; head = this; @@ -61,7 +60,7 @@ void STEPcomplex::Initialize( const char ** names, const char * schnm ) { EntNode * ents = new EntNode( names ), *eptr = ents, *prev = NULL, *enext; const EntityDescriptor * enDesc; - char nm[BUFSIZ]; + char nm[BUFSIZ+1]; bool invalid = false, outOfOrder = false; // Splice out the invalid names from our list: @@ -659,7 +658,7 @@ const char * STEPcomplex::WriteExtMapEntities( std::string & buf, const char * c void STEPcomplex::CopyAs( SDAI_Application_instance * se ) { if( !se->IsComplex() ) { - char errStr[BUFSIZ]; + char errStr[BUFSIZ+1]; cerr << "STEPcomplex::CopyAs() called with non-complex entity: " << __FILE__ << __LINE__ << "\n" << _POC_ "\n"; sprintf( errStr, @@ -700,7 +699,7 @@ SDAI_Application_instance * STEPcomplex::Replicate() { } nameList[i] = ( std::string * )0; if( i == 63 ) { - char errStr[BUFSIZ]; + char errStr[BUFSIZ+1]; cerr << "STEPcomplex::Replicate() name buffer too small: " << __FILE__ << __LINE__ << "\n" << _POC_ "\n"; sprintf( errStr, diff --git a/src/clstepcore/STEPinvAttrList.cc b/src/clstepcore/STEPinvAttrList.cc index 52bdf1ee5..3eaa9d352 100644 --- a/src/clstepcore/STEPinvAttrList.cc +++ b/src/clstepcore/STEPinvAttrList.cc @@ -3,9 +3,8 @@ * derived from STEPattributeList.cc */ -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/STEPinvAttrList.h" +#include "clstepcore/ExpDict.h" invAttrListNodeI::invAttrListNodeI(Inverse_attribute* a, setterI_t s, getterI_t g): invAttrListNode(a), set( s ), get( g ) {} invAttrListNodeA::invAttrListNodeA(Inverse_attribute* a, setterA_t s, getterA_t g): invAttrListNode(a), set( s ), get( g ) {} diff --git a/src/clstepcore/STEPundefined.cc b/src/clstepcore/STEPundefined.cc index 6ca378099..19c63f37d 100644 --- a/src/clstepcore/STEPundefined.cc +++ b/src/clstepcore/STEPundefined.cc @@ -11,9 +11,8 @@ */ #include // to get the BUFSIZ #define -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/STEPundefined.h" /** \class SCLundefined ** helper functions for reading unknown types diff --git a/src/clstepcore/SingleLinkList.cc b/src/clstepcore/SingleLinkList.cc index b13e2061d..19a1f82e7 100644 --- a/src/clstepcore/SingleLinkList.cc +++ b/src/clstepcore/SingleLinkList.cc @@ -10,8 +10,7 @@ * and is not subject to copyright. */ -#include -#include "sc_memmgr.h" +#include "clstepcore/SingleLinkList.h" #include @@ -95,7 +94,7 @@ void SingleLinkList::AppendNode( SingleLinkNode * item ) { } void SingleLinkList::DeleteNode( SingleLinkNode * item ) { - if( head ) { + if( head && item ) { SingleLinkNode * trailer = 0; SingleLinkNode * leader = head; while( leader ) { @@ -111,6 +110,7 @@ void SingleLinkList::DeleteNode( SingleLinkNode * item ) { tail = trailer; } delete item; + return; } else { if( trailer ) { trailer = trailer->NextNode(); diff --git a/src/clstepcore/aggrTypeDescriptor.cc b/src/clstepcore/aggrTypeDescriptor.cc index 91bed40be..b61b08f72 100644 --- a/src/clstepcore/aggrTypeDescriptor.cc +++ b/src/clstepcore/aggrTypeDescriptor.cc @@ -1,4 +1,4 @@ -#include "aggrTypeDescriptor.h" +#include "clstepcore/aggrTypeDescriptor.h" STEPaggregate * AggrTypeDescriptor::CreateAggregate() { if( CreateNewAggr ) { diff --git a/src/clstepcore/attrDescriptor.cc b/src/clstepcore/attrDescriptor.cc index 329d90393..a6a71b65a 100644 --- a/src/clstepcore/attrDescriptor.cc +++ b/src/clstepcore/attrDescriptor.cc @@ -1,4 +1,4 @@ -#include "attrDescriptor.h" +#include "clstepcore/attrDescriptor.h" AttrDescriptor::AttrDescriptor( const char * name, const TypeDescriptor * domainType, Logical optional, Logical unique, AttrType_Enum at, diff --git a/src/clstepcore/attrDescriptorList.cc b/src/clstepcore/attrDescriptorList.cc index c197ac5e2..903180c5b 100644 --- a/src/clstepcore/attrDescriptorList.cc +++ b/src/clstepcore/attrDescriptorList.cc @@ -1,6 +1,6 @@ -#include "attrDescriptorList.h" +#include "clstepcore/attrDescriptorList.h" -#include "attrDescriptor.h" +#include "clstepcore/attrDescriptor.h" AttrDescriptorList::AttrDescriptorList() { } diff --git a/src/clstepcore/collect.cc b/src/clstepcore/collect.cc index 08f2131bb..7a952f556 100644 --- a/src/clstepcore/collect.cc +++ b/src/clstepcore/collect.cc @@ -1,7 +1,7 @@ /*************************************************************************//** * collect.cc \class ComplexCollect * * * - * Description: ComplexCollect is the container structure for all ofthe com- * + * Description: ComplexCollect is the container structure for all of the com-* * plex entity information in a schema. It contains a list of * * ComplexList structures each of which corresponds to one set * * of subtype/supertype information about the schema. This file * @@ -11,8 +11,7 @@ * Date: 11/14/96 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" /** * Inserts a new ComplexList to our list. The ComplexLists are ordered by @@ -85,8 +84,8 @@ ComplexList * ComplexCollect::find( char * name ) { /** * Determines if the parent schema supports the instantiation of a complex - * type consisting of the the entities named in ents. Does so by attempt- - * ing to match ents against the ComplexLists in clists. If one of the + * type consisting of the entities named in ents. Does so by attempting + * to match ents against the ComplexLists in clists. If one of the * nodes of ents has multSupers set to true (it has >1 supertype), it * should be included in >1 CList. A more complicated algorithm is applied * to match it, as described in the commenting. diff --git a/src/clstepcore/complexlist.cc b/src/clstepcore/complexlist.cc index 52eb0a372..3dcdff482 100644 --- a/src/clstepcore/complexlist.cc +++ b/src/clstepcore/complexlist.cc @@ -10,8 +10,7 @@ * Date: 01/07/97 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" /** * Destructor for ComplexList. @@ -144,7 +143,7 @@ bool ComplexList::contains( EntNode * ents ) { ours = ours->next; } if( ours == NULL || *ours > *theirs ) { - // If either of these occured, we couldn't find one of ours which + // If either of these occurred, we couldn't find one of ours which // matched the current "theirs". return false; } diff --git a/src/clstepcore/create_Aggr.cc b/src/clstepcore/create_Aggr.cc index 72f6adb53..e71cfbc86 100644 --- a/src/clstepcore/create_Aggr.cc +++ b/src/clstepcore/create_Aggr.cc @@ -1,5 +1,5 @@ -#include "create_Aggr.h" -#include +#include "clstepcore/create_Aggr.h" +#include "clstepcore/STEPaggregate.h" EnumAggregate * create_EnumAggregate() { return new EnumAggregate; diff --git a/src/clstepcore/derivedAttribute.cc b/src/clstepcore/derivedAttribute.cc index 7fca3b16f..8d21b0884 100644 --- a/src/clstepcore/derivedAttribute.cc +++ b/src/clstepcore/derivedAttribute.cc @@ -1,4 +1,4 @@ -#include "derivedAttribute.h" +#include "clstepcore/derivedAttribute.h" Derived_attribute::Derived_attribute( const char * name, const TypeDescriptor * domainType, Logical optional, Logical unique, AttrType_Enum at, const EntityDescriptor & owner ) diff --git a/src/clstepcore/dict-pic.txt b/src/clstepcore/dict-pic.txt index aea7a746e..79f3399ad 100644 --- a/src/clstepcore/dict-pic.txt +++ b/src/clstepcore/dict-pic.txt @@ -9,7 +9,7 @@ Jeff, This is the layout of the dictionary classes in our toolkit (when the new changes get integrated). This matches Part 23. -// The classes in the heirarchy are the new names for our classes. +// The classes in the hierarchy are the new names for our classes. // DictionaryInstance // | diff --git a/src/clstepcore/dictSchema.cc b/src/clstepcore/dictSchema.cc index 11170d4df..aa87b4586 100644 --- a/src/clstepcore/dictSchema.cc +++ b/src/clstepcore/dictSchema.cc @@ -1,7 +1,7 @@ -#include "dictSchema.h" +#include "clstepcore/dictSchema.h" -#include "typeDescriptor.h" -#include "entityDescriptor.h" +#include "clstepcore/typeDescriptor.h" +#include "clstepcore/entityDescriptor.h" Schema::Schema( const char * schemaName ) : _use_interface_list( new Interface_spec__set ), diff --git a/src/clstepcore/dispnode.cc b/src/clstepcore/dispnode.cc index 2590e034c..15f249d37 100644 --- a/src/clstepcore/dispnode.cc +++ b/src/clstepcore/dispnode.cc @@ -12,13 +12,12 @@ /* $Id: dispnode.cc,v 3.0.1.2 1997/11/05 22:11:39 sauderd DP3.1 $ */ -#include -#include +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" //#include -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/dispnode.h" +#include "clstepcore/dispnodelist.h" // define this to be the name of the display object class StepEntityEditor; diff --git a/src/clstepcore/dispnodelist.cc b/src/clstepcore/dispnodelist.cc index f4d00a6aa..7fbd788c3 100644 --- a/src/clstepcore/dispnodelist.cc +++ b/src/clstepcore/dispnodelist.cc @@ -12,14 +12,13 @@ /* $Id: dispnodelist.cc,v 3.0.1.2 1997/11/05 22:11:40 sauderd DP3.1 $ */ -#include -#include - -#include -#include -#include -#include -#include "sc_memmgr.h" +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" + +#include "clstepcore/mgrnode.h" +#include "clstepcore/mgrnodelist.h" +#include "clstepcore/dispnode.h" +#include "clstepcore/dispnodelist.h" void DisplayNodeList::Remove( GenericNode * node ) { GenNodeList::Remove( node ); diff --git a/src/clstepcore/entityDescriptor.cc b/src/clstepcore/entityDescriptor.cc index 0e58c4db6..764d77066 100644 --- a/src/clstepcore/entityDescriptor.cc +++ b/src/clstepcore/entityDescriptor.cc @@ -1,10 +1,10 @@ #include -#include "entityDescriptor.h" -#include "Registry.h" -#include "attrDescriptor.h" -#include "inverseAttribute.h" -#include "SubSuperIterators.h" +#include "clstepcore/entityDescriptor.h" +#include "clstepcore/Registry.h" +#include "clstepcore/attrDescriptor.h" +#include "clstepcore/inverseAttribute.h" +#include "clstepcore/SubSuperIterators.h" EntityDescriptor::EntityDescriptor( ) : _abstractEntity( LUnknown ), _extMapping( LUnknown ), diff --git a/src/clstepcore/entityDescriptorList.cc b/src/clstepcore/entityDescriptorList.cc index 86d937c76..e23baeabb 100644 --- a/src/clstepcore/entityDescriptorList.cc +++ b/src/clstepcore/entityDescriptorList.cc @@ -1,4 +1,4 @@ -#include "entityDescriptorList.h" +#include "clstepcore/entityDescriptorList.h" EntityDescLinkNode::EntityDescLinkNode() { _entityDesc = 0; diff --git a/src/clstepcore/entlist.cc b/src/clstepcore/entlist.cc index 0dd35803a..e7c0d7c89 100644 --- a/src/clstepcore/entlist.cc +++ b/src/clstepcore/entlist.cc @@ -13,8 +13,7 @@ * Date: 9/18/96 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" /** * Returns the number of EntLists in this's list (EntList->next, next->next diff --git a/src/clstepcore/entnode.cc b/src/clstepcore/entnode.cc index 792489e4b..bc2141360 100644 --- a/src/clstepcore/entnode.cc +++ b/src/clstepcore/entnode.cc @@ -11,8 +11,7 @@ * Date: 9/18/96 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" /** * Given a list of entity names, creates a sorted linked list of EntNodes diff --git a/src/clstepcore/enumTypeDescriptor.cc b/src/clstepcore/enumTypeDescriptor.cc index 9200b196f..61c4eef0f 100644 --- a/src/clstepcore/enumTypeDescriptor.cc +++ b/src/clstepcore/enumTypeDescriptor.cc @@ -1,4 +1,4 @@ -#include "enumTypeDescriptor.h" +#include "clstepcore/enumTypeDescriptor.h" /* * why have EnumTypeDescriptor + EnumerationTypeDescriptor ??? @@ -25,7 +25,7 @@ SDAI_Enum * EnumTypeDescriptor::CreateEnum() { } const char * EnumTypeDescriptor::GenerateExpress( std::string & buf ) const { - char tmp[BUFSIZ]; + char tmp[BUFSIZ+1]; buf = "TYPE "; buf.append( StrToLower( Name(), tmp ) ); buf.append( " = ENUMERATION OF \n (" ); diff --git a/src/clstepcore/explicitItemId.cc b/src/clstepcore/explicitItemId.cc index c229f6369..b7177c189 100644 --- a/src/clstepcore/explicitItemId.cc +++ b/src/clstepcore/explicitItemId.cc @@ -1,4 +1,4 @@ -#include "explicitItemId.h" +#include "clstepcore/explicitItemId.h" Explicit_item_id::Explicit_item_id() { _local_definition = 0; diff --git a/src/clstepcore/globalRule.cc b/src/clstepcore/globalRule.cc index b6fdeb19a..227562faa 100644 --- a/src/clstepcore/globalRule.cc +++ b/src/clstepcore/globalRule.cc @@ -1,4 +1,4 @@ -#include "globalRule.h" +#include "clstepcore/globalRule.h" Global_rule::Global_rule() : _entities( 0 ), _where_rules( 0 ), _parent_schema( 0 ) { diff --git a/src/clstepcore/implicitItemId.cc b/src/clstepcore/implicitItemId.cc index 1961727af..963844314 100644 --- a/src/clstepcore/implicitItemId.cc +++ b/src/clstepcore/implicitItemId.cc @@ -1,4 +1,4 @@ -#include "implicitItemId.h" +#include "clstepcore/implicitItemId.h" Implicit_item_id::Implicit_item_id() { _local_definition = 0; diff --git a/src/clstepcore/instmgr.cc b/src/clstepcore/instmgr.cc index 702ea0869..6b6cc6a7e 100644 --- a/src/clstepcore/instmgr.cc +++ b/src/clstepcore/instmgr.cc @@ -16,9 +16,8 @@ // ////////////////////////////////////////////////////////////////////////////// -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" +#include "clstepcore/instmgr.h" /////////////////////////////////////////////////////////////////////////////// // debug_level >= 2 => tells when a command is chosen @@ -94,7 +93,7 @@ void InstMgr::DeleteInstances() { enum Severity InstMgr::VerifyInstances( ErrorDescriptor & err ) { int errorCount = 0; - char errbuf[BUFSIZ]; + char errbuf[BUFSIZ+1]; int n = InstanceCount(); MgrNode * mn; diff --git a/src/clstepcore/interfaceSpec.cc b/src/clstepcore/interfaceSpec.cc index eb0fecf3a..b0ed39bc5 100644 --- a/src/clstepcore/interfaceSpec.cc +++ b/src/clstepcore/interfaceSpec.cc @@ -1,4 +1,4 @@ -#include "interfaceSpec.h" +#include "clstepcore/interfaceSpec.h" Interface_spec__set::Interface_spec__set( int defaultSize ) { _bufsize = defaultSize; diff --git a/src/clstepcore/interfacedItem.cc b/src/clstepcore/interfacedItem.cc index 749a5922e..9ddb5b5a5 100644 --- a/src/clstepcore/interfacedItem.cc +++ b/src/clstepcore/interfacedItem.cc @@ -1,4 +1,4 @@ -#include "interfacedItem.h" +#include "clstepcore/interfacedItem.h" Interfaced_item::Interfaced_item() { } diff --git a/src/clstepcore/inverseAttribute.cc b/src/clstepcore/inverseAttribute.cc index eeccec90a..512c71c34 100644 --- a/src/clstepcore/inverseAttribute.cc +++ b/src/clstepcore/inverseAttribute.cc @@ -1,4 +1,4 @@ -#include "inverseAttribute.h" +#include "clstepcore/inverseAttribute.h" #include const char * Inverse_attribute::AttrExprDefStr( std::string & s ) const { diff --git a/src/clstepcore/inverseAttributeList.cc b/src/clstepcore/inverseAttributeList.cc index 22591d41c..2dd7d46b0 100644 --- a/src/clstepcore/inverseAttributeList.cc +++ b/src/clstepcore/inverseAttributeList.cc @@ -1,5 +1,5 @@ -#include "inverseAttributeList.h" -#include "inverseAttribute.h" +#include "clstepcore/inverseAttributeList.h" +#include "clstepcore/inverseAttribute.h" Inverse_attributeLinkNode::Inverse_attributeLinkNode() { _invAttr = 0; diff --git a/src/clstepcore/match-ors.cc b/src/clstepcore/match-ors.cc index 5f17f7d93..72427ca6b 100644 --- a/src/clstepcore/match-ors.cc +++ b/src/clstepcore/match-ors.cc @@ -13,8 +13,7 @@ * Date: 10/17/96 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" /** * Loops through descendants of this, invoking their matchOR functions. diff --git a/src/clstepcore/mgrnode.cc b/src/clstepcore/mgrnode.cc index 8e44443ee..a7d13b538 100644 --- a/src/clstepcore/mgrnode.cc +++ b/src/clstepcore/mgrnode.cc @@ -12,17 +12,16 @@ /* $Id: mgrnode.cc,v 3.0.1.3 1997/11/05 22:11:37 sauderd DP3.1 $ */ -#include -#include -#include -#include +#include "clstepcore/mgrnode.h" +#include "clstepcore/mgrnodelist.h" +#include "clstepcore/dispnode.h" +#include "clstepcore/dispnodelist.h" -#include +#include "clstepcore/instmgr.h" //#include -#include +#include "clstepcore/sdai.h" #include -#include "sc_memmgr.h" void * MgrNode::SEE() { return ( di ? di->SEE() : 0 ); diff --git a/src/clstepcore/mgrnodearray.cc b/src/clstepcore/mgrnodearray.cc index 23069f02b..d777b596f 100644 --- a/src/clstepcore/mgrnodearray.cc +++ b/src/clstepcore/mgrnodearray.cc @@ -32,12 +32,11 @@ static int PrintFunctionTrace = 2; // values within functions get printed out //static int PrintValues = 3; -#include +#include "clstepcore/mgrnodearray.h" //#include -#include +#include "clstepcore/sdai.h" #include // to get bcopy() - ANSI -#include "sc_memmgr.h" ////////////////////////////////////////////////////////////////////////////// // class MgrNodeArray member functions diff --git a/src/clstepcore/mgrnodelist.cc b/src/clstepcore/mgrnodelist.cc index 9bff8e254..77ee20100 100644 --- a/src/clstepcore/mgrnodelist.cc +++ b/src/clstepcore/mgrnodelist.cc @@ -12,11 +12,10 @@ /* $Id: mgrnodelist.cc,v 3.0.1.2 1997/11/05 22:11:39 sauderd DP3.1 $ */ -#include -#include -#include -#include -#include "sc_memmgr.h" +#include "clstepcore/mgrnode.h" +#include "clstepcore/mgrnodelist.h" +#include "clstepcore/dispnode.h" +#include "clstepcore/dispnodelist.h" MgrNodeList::MgrNodeList( stateEnum type ) : GenNodeList( new MgrNode() ) { // if(debug_level >= PrintFunctionTrace) diff --git a/src/clstepcore/multlist.cc b/src/clstepcore/multlist.cc index aa0f5e42c..b36488377 100644 --- a/src/clstepcore/multlist.cc +++ b/src/clstepcore/multlist.cc @@ -13,8 +13,7 @@ * Date: 9/18/96 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" /** * Deletes the childList of this, before this is deleted. @@ -218,7 +217,7 @@ bool JoinList::acceptChoice( EntNode * ents ) { if( child->viable >= MATCHSOME ) { // Only mark children which have new nodes they can mark. (This // condition is important. Sometimes, there will be children who - // can mark but whose vaiable val = SATISFIED. This will be the + // can mark but whose variable val = SATISFIED. This will be the // case if there's another EntList with higher priority which can // also mark this node. (For example, if an AND has an OR and a // SIMPLE child, the SIMPLE wins so that we'll have fewer OR diff --git a/src/clstepcore/needFunc.cc b/src/clstepcore/needFunc.cc index eea46ddb5..e72215fed 100644 --- a/src/clstepcore/needFunc.cc +++ b/src/clstepcore/needFunc.cc @@ -1,5 +1,4 @@ -#include -#include "sc_memmgr.h" +#include "clstepcore/needFunc.h" /////////////////////////////////////////////////////////////////////////////// // Function defined as a stub (necessary to use the scl) diff --git a/src/clstepcore/non-ors.cc b/src/clstepcore/non-ors.cc index 14607f606..14b6a4f6c 100644 --- a/src/clstepcore/non-ors.cc +++ b/src/clstepcore/non-ors.cc @@ -10,8 +10,7 @@ * Date: 10/17/96 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" /** * Checks if we match the nodes of ents. If only one unmarked is left diff --git a/src/clstepcore/orlist.cc b/src/clstepcore/orlist.cc index b820bea53..f5fa185b0 100644 --- a/src/clstepcore/orlist.cc +++ b/src/clstepcore/orlist.cc @@ -10,8 +10,7 @@ * Date: 9/18/96 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" /** * Check if we matched nm. We have two possibilities here: If we have a diff --git a/src/clstepcore/print.cc b/src/clstepcore/print.cc index 2139d1f61..63759b9fc 100644 --- a/src/clstepcore/print.cc +++ b/src/clstepcore/print.cc @@ -7,8 +7,7 @@ * Date: 10/31/96 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" // Local function prototypes: static char * joinText( JoinType, char * ); diff --git a/src/clstepcore/read_func.cc b/src/clstepcore/read_func.cc index 395e52cfd..9f31db401 100644 --- a/src/clstepcore/read_func.cc +++ b/src/clstepcore/read_func.cc @@ -1,11 +1,10 @@ -#include +#include "clutils/errordesc.h" #include -#include -#include -#include -#include "Str.h" -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" +#include "clstepcore/read_func.h" +#include "clstepcore/STEPattribute.h" +#include "clutils/Str.h" const int RealNumPrecision = REAL_NUM_PRECISION; @@ -467,7 +466,7 @@ void PushPastString( istream & in, std::string & s, ErrorDescriptor * err ) { * This is used to read aggregates that are part of multidimensional aggregates. */ void PushPastImbedAggr( istream & in, std::string & s, ErrorDescriptor * err ) { - char messageBuf[BUFSIZ]; + char messageBuf[BUFSIZ+1]; messageBuf[0] = '\0'; char c; @@ -506,7 +505,7 @@ void PushPastImbedAggr( istream & in, std::string & s, ErrorDescriptor * err ) { * to contain an aggregate as an element. */ void PushPastAggr1Dim( istream & in, std::string & s, ErrorDescriptor * err ) { - char messageBuf[BUFSIZ]; + char messageBuf[BUFSIZ+1]; messageBuf[0] = '\0'; char c; diff --git a/src/clstepcore/schRename.cc b/src/clstepcore/schRename.cc index b7159a6e0..6e5e12686 100644 --- a/src/clstepcore/schRename.cc +++ b/src/clstepcore/schRename.cc @@ -1,4 +1,4 @@ -#include "schRename.h" +#include "clstepcore/schRename.h" /** diff --git a/src/clstepcore/sdai.cc b/src/clstepcore/sdai.cc index 731a381f5..ec96a63b3 100644 --- a/src/clstepcore/sdai.cc +++ b/src/clstepcore/sdai.cc @@ -1,8 +1,7 @@ #include #include -#include -#include "sc_memmgr.h" +#include "clstepcore/sdai.h" const char * SCLversion = "STEPcode, github.com/stepcode/stepcode"; diff --git a/src/clstepcore/sdaiApplication_instance.cc b/src/clstepcore/sdaiApplication_instance.cc index 2bbf6b31c..c44a2c5ea 100644 --- a/src/clstepcore/sdaiApplication_instance.cc +++ b/src/clstepcore/sdaiApplication_instance.cc @@ -11,17 +11,15 @@ */ #include -#include -#include -#include -#include -#include //for ReadTokenSeparator, used when comments are inside entities +#include "clstepcore/sdai.h" +#include "clstepcore/instmgr.h" +#include "clstepcore/STEPcomplex.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/read_func.h" //for ReadTokenSeparator, used when comments are inside entities -#include "sdaiApplication_instance.h" +#include "clstepcore/sdaiApplication_instance.h" #include "superInvAttrIter.h" -#include - SDAI_Application_instance NilSTEPentity; bool isNilSTEPentity( const SDAI_Application_instance * ai ) { @@ -104,7 +102,7 @@ void SDAI_Application_instance::InitIAttrs() { } SDAI_Application_instance * SDAI_Application_instance::Replicate() { - char errStr[BUFSIZ]; + char errStr[BUFSIZ+1]; if( IsComplex() ) { cerr << "STEPcomplex::Replicate() should be called: " << __FILE__ << __LINE__ << "\n" << _POC_ "\n"; @@ -172,10 +170,6 @@ void SDAI_Application_instance::AppendMultInstance( SDAI_Application_instance * } } -const EntityDescriptor* SDAI_Application_instance::getEDesc() const { - return eDesc; -} - // BUG implement this -- FIXME function is never used SDAI_Application_instance * SDAI_Application_instance::GetMiEntity( char * entName ) { std::string s1, s2; @@ -422,7 +416,7 @@ void SDAI_Application_instance::WriteValuePairs( ostream & out, const char * SDAI_Application_instance::STEPwrite( std::string & buf, const char * currSch ) { buf.clear(); - char instanceInfo[BUFSIZ]; + char instanceInfo[BUFSIZ+1]; std::string tmp; sprintf( instanceInfo, "#%d=%s(", STEPfile_id, StrToUpper( EntityName( currSch ), tmp ) ); @@ -444,7 +438,7 @@ const char * SDAI_Application_instance::STEPwrite( std::string & buf, const char } void SDAI_Application_instance::PrependEntityErrMsg() { - char errStr[BUFSIZ]; + char errStr[BUFSIZ+1]; errStr[0] = '\0'; if( _error.severity() == SEVERITY_NULL ) { @@ -465,7 +459,7 @@ void SDAI_Application_instance::PrependEntityErrMsg() { ******************************************************************/ void SDAI_Application_instance::STEPread_error( char c, int i, istream & in, const char * schnm ) { (void) in; - char errStr[BUFSIZ]; + char errStr[BUFSIZ+1]; errStr[0] = '\0'; if( _error.severity() == SEVERITY_NULL ) { @@ -478,7 +472,7 @@ void SDAI_Application_instance::STEPread_error( char c, int i, istream & in, con if( ( i >= 0 ) && ( i < attributes.list_length() ) ) { // i is an attribute Error().GreaterSeverity( SEVERITY_WARNING ); sprintf( errStr, " invalid data before type \'%s\'\n", - attributes[i].TypeName() ); + attributes[i].TypeName().c_str() ); _error.AppendToDetailMsg( errStr ); } else { Error().GreaterSeverity( SEVERITY_INPUT_ERROR ); @@ -517,7 +511,7 @@ Severity SDAI_Application_instance::STEPread( int id, int idIncr, const char * currSch, bool useTechCor, bool strict ) { STEPfile_id = id; char c = '\0'; - char errStr[BUFSIZ]; + char errStr[BUFSIZ+1]; errStr[0] = '\0'; Severity severe; int i = 0; @@ -669,7 +663,7 @@ Severity SDAI_Application_instance::STEPread( int id, int idIncr, SDAI_Application_instance * ReadEntityRef( istream & in, ErrorDescriptor * err, const char * tokenList, InstMgrBase * instances, int addFileId ) { char c; - char errStr[BUFSIZ]; + char errStr[BUFSIZ+1]; errStr[0] = '\0'; in >> ws; @@ -679,6 +673,7 @@ SDAI_Application_instance * ReadEntityRef( istream & in, ErrorDescriptor * err, err->AppendToDetailMsg( "Use of @ instead of # to identify entity.\n" ); err->GreaterSeverity( SEVERITY_WARNING ); // no break statement here on purpose + [[gnu::fallthrough]]; case '#': { int id = -1; in >> id; @@ -761,7 +756,7 @@ Severity EntityValidLevel( SDAI_Application_instance * se, // to match. (this must be an // EntityDescriptor) ErrorDescriptor * err ) { - char messageBuf [BUFSIZ]; + char messageBuf [BUFSIZ+1]; messageBuf[0] = '\0'; if( !ed || ( ed->NonRefType() != ENTITY_TYPE ) ) { @@ -790,9 +785,9 @@ Severity EntityValidLevel( SDAI_Application_instance * se, // DAVE: Can an entity be used in an Express TYPE so that this // EntityDescriptor would have type REFERENCE_TYPE -- it looks like NO - else if( se->getEDesc() ) { + else if( se->eDesc ) { // is se a descendant of ed? - if( se->getEDesc()->IsA( ed ) ) { + if( se->eDesc->IsA( ed ) ) { return SEVERITY_NULL; } else { if( se->IsComplex() ) { @@ -830,7 +825,7 @@ Severity EntityValidLevel( SDAI_Application_instance * se, * DAVE: Is this needed will sscanf return 1 if assignment suppression is used? */ int SetErrOnNull( const char * attrValue, ErrorDescriptor * error ) { - char scanBuf[BUFSIZ]; + char scanBuf[BUFSIZ+1]; scanBuf[0] = '\0'; std::stringstream fmtstr; @@ -858,9 +853,9 @@ Severity EntityValidLevel( const char * attrValue, // string contain entity ref // to match. (this must be an // EntityDescriptor) ErrorDescriptor * err, InstMgrBase * im, int clearError ) { - char tmp [BUFSIZ]; + char tmp [BUFSIZ+1]; tmp[0] = '\0'; - char messageBuf [BUFSIZ]; + char messageBuf [BUFSIZ+1]; messageBuf[0] = '\0'; std::stringstream fmtstr1, fmtstr2; @@ -883,9 +878,12 @@ Severity EntityValidLevel( const char * attrValue, // string contain entity ref if( ( found1 > 0 ) || ( found2 > 0 ) ) { if( ( found1 == 2 ) || ( found2 == 2 ) ) { - sprintf( messageBuf, - " Attribute's Entity Reference %s is %s data \'%s\'.\n", - attrValue, "followed by invalid", tmp ); + int ocnt = snprintf( messageBuf, BUFSIZ, + " Attribute's Entity Reference %s is %s data \'%s\'.\n", + attrValue, "followed by invalid", tmp ); + if( ocnt < BUFSIZ ) { + fprintf( stderr, "Warning - truncation of Attribute's Entry Reference msg\n" ); + } err->AppendToUserMsg( messageBuf ); err->AppendToDetailMsg( messageBuf ); err->GreaterSeverity( SEVERITY_WARNING ); @@ -956,7 +954,7 @@ const SDAI_Application_instance::iAMap_t::value_type SDAI_Application_instance:: } iAstruct z; memset( &z, 0, sizeof z ); - iAMap_t::value_type nil( (Inverse_attribute *) nullptr, z ); + iAMap_t::value_type nil( ( Inverse_attribute * ) NULL, z ); return nil; } diff --git a/src/clstepcore/sdaiSelect.cc b/src/clstepcore/sdaiSelect.cc index 9837540c9..95e6d83bc 100644 --- a/src/clstepcore/sdaiSelect.cc +++ b/src/clstepcore/sdaiSelect.cc @@ -11,11 +11,11 @@ */ #include // to get the BUFSIZ #define -#include +#include "clstepcore/ExpDict.h" #include #include -#include -#include +#include "clstepcore/sdai.h" +#include "clstepcore/STEPattribute.h" #ifdef SC_LOGGING #include @@ -242,7 +242,7 @@ Severity SDAI_Select::STEPread( istream & in, ErrorDescriptor * err, /** ** This section of code is used to read a value belonging to a select ** contained in another select. If you have read the text part of the - ** TYPED_PARAMETER and it needs to fall down thru some levels of contained + ** TYPED_PARAMETER and it needs to fall down through some levels of contained ** select types, then the text is passed down to each select in the utype ** parameter as STEPread is called on each contained select type.DAS 2/4/97 */ @@ -514,7 +514,7 @@ Severity SDAI_Select::STEPread( istream & in, ErrorDescriptor * err, STEPread_content( in, instances, 0, addFileId ); } - else { // ERROR -- the type wasn\'t one of the choices + else { // ERROR -- the type wasn't one of the choices err->AppendToDetailMsg( "The type of the SELECT type is not valid.\n" ); err->GreaterSeverity( SEVERITY_WARNING ); diff --git a/src/clstepcore/selectTypeDescriptor.cc b/src/clstepcore/selectTypeDescriptor.cc index a7c0ad032..e143a3a30 100644 --- a/src/clstepcore/selectTypeDescriptor.cc +++ b/src/clstepcore/selectTypeDescriptor.cc @@ -1,4 +1,4 @@ -#include "selectTypeDescriptor.h" +#include "clstepcore/selectTypeDescriptor.h" /////////////////////////////////////////////////////////////////////////////// // SelectTypeDescriptor functions diff --git a/src/clstepcore/superInvAttrIter.h b/src/clstepcore/superInvAttrIter.h index bfe73dc17..6228b67be 100644 --- a/src/clstepcore/superInvAttrIter.h +++ b/src/clstepcore/superInvAttrIter.h @@ -1,8 +1,8 @@ #ifndef SUPERINVATTRITER_H #define SUPERINVATTRITER_H -#include "SubSuperIterators.h" -#include "ExpDict.h" +#include "clstepcore/SubSuperIterators.h" +#include "clstepcore/ExpDict.h" /** * this class implements an iterator for inverse attributes in an EntityDescriptor's supertypes diff --git a/src/clstepcore/test/CMakeLists.txt b/src/clstepcore/test/CMakeLists.txt index 3ed91a9f2..ea37cb0cd 100644 --- a/src/clstepcore/test/CMakeLists.txt +++ b/src/clstepcore/test/CMakeLists.txt @@ -1,14 +1,13 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.12) #c++ tests for clstepcore include_directories( ${SC_SOURCE_DIR}/src/cldai ${SC_SOURCE_DIR}/src/cleditor - ${SC_SOURCE_DIR}/src/clutils ${SC_SOURCE_DIR}/src/base ${SC_SOURCE_DIR}/src/clstepcore ) function(add_stepcore_test name libs) - SC_ADDEXEC(tst_${name} test_${name}.cc "${libs}" "TESTABLE") + SC_ADDEXEC(tst_${name} SOURCES test_${name}.cc LINK_LIBRARIES ${libs} TESTABLE) add_test(NAME build_cpp_${name} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} --build . @@ -21,10 +20,10 @@ function(add_stepcore_test name libs) set_tests_properties(test_${name} PROPERTIES LABELS cpp_unit_stepcore DEPENDS build_cpp_${name}) endfunction(add_stepcore_test name libs) -add_stepcore_test("SupertypesIterator" "stepcore;steputils;stepeditor;stepdai;base") #all these libs are necessary? -add_stepcore_test("operators_STEPattribute" "stepcore;steputils;stepeditor;stepdai;base") -add_stepcore_test("operators_SDAI_Select" "stepcore;steputils;stepeditor;stepdai;base") -add_stepcore_test("null_attr" "stepcore;steputils;stepeditor;stepdai;base") +add_stepcore_test("SupertypesIterator" "stepcore;steputils;stepeditor;stepdai") #all these libs are necessary? +add_stepcore_test("operators_STEPattribute" "stepcore;steputils;stepeditor;stepdai") +add_stepcore_test("operators_SDAI_Select" "stepcore;steputils;stepeditor;stepdai") +add_stepcore_test("null_attr" "stepcore;steputils;stepeditor;stepdai") # Local Variables: # tab-width: 8 diff --git a/src/clstepcore/test/test_SupertypesIterator.cc b/src/clstepcore/test/test_SupertypesIterator.cc index f557d7c72..084189bf0 100644 --- a/src/clstepcore/test/test_SupertypesIterator.cc +++ b/src/clstepcore/test/test_SupertypesIterator.cc @@ -4,8 +4,8 @@ //subtypesiterator shouldn't need tested separately from supertypesiterator since there is very little difference -#include "SubSuperIterators.h" -#include "ExpDict.h" +#include "clstepcore/SubSuperIterators.h" +#include "clstepcore/ExpDict.h" #include int main( int /*argc*/, char ** /*argv*/ ) { diff --git a/src/clstepcore/test/test_null_attr.cc b/src/clstepcore/test/test_null_attr.cc index 0c96c5798..95c7dcd02 100644 --- a/src/clstepcore/test/test_null_attr.cc +++ b/src/clstepcore/test/test_null_attr.cc @@ -1,6 +1,6 @@ -#include -#include -#include +#include "clstepcore/ExpDict.h" +#include "clstepcore/STEPattribute.h" +#include "cldai/sdaiString.h" AttrDescriptor *ad = 0; EntityDescriptor *ed = 0; diff --git a/src/clstepcore/test/test_operators_SDAI_Select.cc b/src/clstepcore/test/test_operators_SDAI_Select.cc index fcb6cde4d..b82d20ddc 100644 --- a/src/clstepcore/test/test_operators_SDAI_Select.cc +++ b/src/clstepcore/test/test_operators_SDAI_Select.cc @@ -6,9 +6,9 @@ #include -#include "ExpDict.h" -#include "baseType.h" -#include "sdaiSelect.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/baseType.h" +#include "clstepcore/sdaiSelect.h" using namespace std; diff --git a/src/clstepcore/test/test_operators_STEPattribute.cc b/src/clstepcore/test/test_operators_STEPattribute.cc index abd396816..a64d274de 100644 --- a/src/clstepcore/test/test_operators_STEPattribute.cc +++ b/src/clstepcore/test/test_operators_STEPattribute.cc @@ -1,7 +1,7 @@ ///test constructors, destructor, shallow copy, assignment operators for STEPattribute -#include -#include +#include "clstepcore/STEPattribute.h" +#include "clstepcore/ExpDict.h" #include diff --git a/src/clstepcore/trynext.cc b/src/clstepcore/trynext.cc index 145af7699..dd2941edd 100644 --- a/src/clstepcore/trynext.cc +++ b/src/clstepcore/trynext.cc @@ -11,8 +11,7 @@ * Date: 10/24/96 * *****************************************************************************/ -#include "complexSupport.h" -#include "sc_memmgr.h" +#include "clstepcore/complexSupport.h" // Local function prototypes: static EntList * firstCandidate( EntList * ); diff --git a/src/clstepcore/typeDescriptor.cc b/src/clstepcore/typeDescriptor.cc index e37d931bb..1d654f609 100644 --- a/src/clstepcore/typeDescriptor.cc +++ b/src/clstepcore/typeDescriptor.cc @@ -1,4 +1,4 @@ -#include "typeDescriptor.h" +#include "clstepcore/typeDescriptor.h" TypeDescriptor::TypeDescriptor( ) : _name( 0 ), altNames( 0 ), _fundamentalType( UNKNOWN_TYPE ), @@ -75,7 +75,7 @@ bool TypeDescriptor::CurrName( const char * other, const char * schNm ) const { // other better = the alt name. return ( !StrCmpIns( _altname, other ) ); } else { - // If we have no desginated alternate name when the current schema = + // If we have no designated alternate name when the current schema = // schNm, other must = our _name. return ( OurName( other ) ); } @@ -132,7 +132,7 @@ void TypeDescriptor::AttrTypeName( std::string & buf, const char * schnm ) const } const char * TypeDescriptor::GenerateExpress( std::string & buf ) const { - char tmp[BUFSIZ]; + char tmp[BUFSIZ+1]; buf = "TYPE "; buf.append( StrToLower( Name(), tmp ) ); buf.append( " = " ); diff --git a/src/clstepcore/typeDescriptorList.cc b/src/clstepcore/typeDescriptorList.cc index f47e8f502..bbc91de9e 100644 --- a/src/clstepcore/typeDescriptorList.cc +++ b/src/clstepcore/typeDescriptorList.cc @@ -1,4 +1,4 @@ -#include "typeDescriptorList.h" +#include "clstepcore/typeDescriptorList.h" TypeDescLinkNode::TypeDescLinkNode() { _typeDesc = 0; diff --git a/src/clstepcore/typeOrRuleVar.cc b/src/clstepcore/typeOrRuleVar.cc index 0b06f1949..c9b823cbf 100644 --- a/src/clstepcore/typeOrRuleVar.cc +++ b/src/clstepcore/typeOrRuleVar.cc @@ -1,4 +1,4 @@ -#include "typeOrRuleVar.h" +#include "clstepcore/typeOrRuleVar.h" #include diff --git a/src/clstepcore/uniquenessRule.cc b/src/clstepcore/uniquenessRule.cc index 038f1a68f..d22bf2c2c 100644 --- a/src/clstepcore/uniquenessRule.cc +++ b/src/clstepcore/uniquenessRule.cc @@ -1,4 +1,4 @@ -#include "uniquenessRule.h" +#include "clstepcore/uniquenessRule.h" #include diff --git a/src/clstepcore/whereRule.cc b/src/clstepcore/whereRule.cc index e60c64940..191b1ec36 100644 --- a/src/clstepcore/whereRule.cc +++ b/src/clstepcore/whereRule.cc @@ -1,4 +1,4 @@ -#include "whereRule.h" +#include "clstepcore/whereRule.h" Where_rule::Where_rule() { _type_or_rule = 0; diff --git a/src/clutils/CMakeLists.txt b/src/clutils/CMakeLists.txt index 22506bf00..27cb08745 100644 --- a/src/clutils/CMakeLists.txt +++ b/src/clutils/CMakeLists.txt @@ -1,5 +1,4 @@ - -set(LIBSTEPUTILS_SRCS +set(UTILS_SRCS Str.cc dirobj.cc gennode.cc @@ -9,30 +8,25 @@ set(LIBSTEPUTILS_SRCS errordesc.cc ) -set(SC_CLUTILS_HDRS - dirobj.h - errordesc.h - gennodearray.h - gennode.h - gennodelist.h - sc_hash.h - Str.h - ) - include_directories( - ${SC_SOURCE_DIR}/src/base ${SC_BINARY_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR} ) -SC_ADDLIB(steputils "${LIBSTEPUTILS_SRCS}" "base") - -if(MINGW OR MSVC OR BORLAND) - target_link_libraries(steputils shlwapi.lib) +if(BUILD_SHARED_LIBS) + SC_ADDLIB(steputils SHARED SOURCES ${UTILS_SRCS}) + if(WIN32) + target_compile_definitions(steputils PRIVATE SC_UTILS_DLL_EXPORTS) + target_link_libraries(steputils shlwapi) + endif() endif() -install(FILES ${SC_CLUTILS_HDRS} - DESTINATION ${INCLUDE_INSTALL_DIR}/stepcode/clutils) +if(BUILD_STATIC_LIBS) + SC_ADDLIB(steputils-static STATIC SOURCES ${UTILS_SRCS}) + if(WIN32) + target_link_libraries(steputils-static shlwapi) + endif() +endif() # Local Variables: # tab-width: 8 diff --git a/src/clutils/Str.cc b/src/clutils/Str.cc index ba36cd610..1f6a3dce3 100644 --- a/src/clutils/Str.cc +++ b/src/clutils/Str.cc @@ -9,7 +9,7 @@ * and is not subject to copyright. */ -#include "Str.h" +#include "clutils/Str.h" #include #include @@ -53,7 +53,7 @@ char * StrToLower( const char * strOld, char * strNew ) { } const char * StrToLower( const char * word, std::string & s ) { - char newword [BUFSIZ]; + char newword [BUFSIZ+1]; int i = 0; while( word [i] != '\0' ) { @@ -66,7 +66,7 @@ const char * StrToLower( const char * word, std::string & s ) { } const char * StrToUpper( const char * word, std::string & s ) { - char newword [BUFSIZ]; + char newword [BUFSIZ+1]; int i = 0; while( word [i] != '\0' ) { @@ -79,7 +79,7 @@ const char * StrToUpper( const char * word, std::string & s ) { } const char * StrToConstant( const char * word, std::string & s ) { - char newword [BUFSIZ]; + char newword [BUFSIZ+1]; int i = 0; while( word [i] != '\0' ) { @@ -179,7 +179,7 @@ std::string GetLiteralStr( istream & in, ErrorDescriptor * err ) { ******************************************************************/ const char * PrettyTmpName( const char * oldname ) { int i = 0; - static char newname [BUFSIZ]; + static char newname [BUFSIZ+1]; newname [0] = '\0'; while( ( oldname [i] != '\0' ) && ( i < BUFSIZ ) ) { newname [i] = ToLower( oldname [i] ); @@ -228,7 +228,7 @@ char * PrettyNewName( const char * oldname ) { *** the value. *** If the input stream can be readable again then -*** - any error states set for the the stream are cleared. +*** - any error states set for the stream are cleared. *** - white space skipped in the input stream *** - if EOF is encountered it returns *** otherwise it peeks at the next character diff --git a/src/clutils/dirobj.cc b/src/clutils/dirobj.cc index 162beada8..e0e3f970a 100644 --- a/src/clutils/dirobj.cc +++ b/src/clutils/dirobj.cc @@ -39,8 +39,8 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include -#include +#include "config.h" +#include "clutils/dirobj.h" #ifdef HAVE_DIRENT_H # include #endif @@ -52,13 +52,12 @@ #include #include +#include -#if defined(__WIN32__) +#ifdef _WIN32 #include #endif -#include - /////////////////////////////////////////////////////////////////////////////// // // Create a new DirObj object. @@ -145,7 +144,7 @@ int DirObj::Index( const char * name ) { bool DirObj::Reset( const std::string & path ) { bool successful = IsADirectory( path.c_str() ); if( successful ) { -#ifdef __WIN32__ +#ifdef _WIN32 WIN32_FIND_DATA FindFileData; HANDLE hFind; @@ -182,7 +181,7 @@ bool DirObj::Reset( const std::string & path ) { /////////////////////////////////////////////////////////////////////////////// bool DirObj::IsADirectory( const char * path ) { -#if defined(__WIN32__) +#ifdef _WIN32 if( PathIsDirectory( path ) ) { return true; } @@ -217,7 +216,7 @@ bool DirObj::IsADirectory( const char * path ) { std::string DirObj::Normalize( const std::string & path ) { std::string buf; const char * slash; -#if defined(__WIN32__) +#ifdef _WIN32 char b[MAX_PATH]; PathCanonicalize( b, path.c_str() ); slash = "\\"; @@ -231,7 +230,7 @@ std::string DirObj::Normalize( const std::string & path ) { } else { buf.assign( b ); -#if !defined(__WIN32__) +#if !defined(_WIN32) free(b); #endif } @@ -254,12 +253,13 @@ std::string DirObj::Normalize( const std::string & path ) { /////////////////////////////////////////////////////////////////////////////// const char * DirObj::ValidDirectories( const char * path ) { -#ifdef __WIN32__ +#ifdef _WIN32 static char buf[MAX_PATH + 1]; + strncpy(buf, path, MAX_PATH); #else static char buf[MAXPATHLEN + 1]; + strncpy(buf, path, MAXPATHLEN); #endif - strcpy( buf, path ); int i = strlen( path ); while( !IsADirectory( RealPath( buf ) ) && i >= 0 ) { @@ -308,7 +308,7 @@ void DirObj::InsertFile( const char * f, int index ) { CheckIndex( index ); spot = &fileList[index]; } -#ifdef __MSVC__ +#ifdef _MSC_VER char * string = _strdup( f ); #else char * string = strdup( f ); @@ -325,8 +325,8 @@ void DirObj::InsertFile( const char * f, int index ) { void DirObj::RemoveFile( int index ) { if( index < --fileCount ) { + free(fileList[index]); const char ** spot = ( const char ** )&fileList[index]; - delete spot; memmove( spot, spot + 1, ( fileCount - index )*sizeof( char * ) ); } } diff --git a/src/clutils/errordesc.cc b/src/clutils/errordesc.cc index 061b9a4e9..17a2de465 100644 --- a/src/clutils/errordesc.cc +++ b/src/clutils/errordesc.cc @@ -10,9 +10,8 @@ * and is not subject to copyright. */ -#include -#include -#include +#include "clutils/errordesc.h" +#include "clutils/Str.h" DebugLevel ErrorDescriptor::_debug_level = DEBUG_OFF; ostream * ErrorDescriptor::_out = 0; @@ -131,7 +130,7 @@ void ErrorDescriptor::PrependToUserMsg( const char * msg ) { } void ErrorDescriptor::AppendToUserMsg( const char c ) { - _userMsg.append( &c ); + _userMsg.push_back( c ); } void ErrorDescriptor::AppendToUserMsg( const char * msg ) { @@ -147,7 +146,7 @@ void ErrorDescriptor::PrependToDetailMsg( const char * msg ) { } void ErrorDescriptor::AppendToDetailMsg( const char c ) { - _detailMsg.append( &c ); + _detailMsg.push_back( c ); } void ErrorDescriptor::AppendToDetailMsg( const char * msg ) { diff --git a/src/clutils/gennode.cc b/src/clutils/gennode.cc index 3036ab19d..c8a993632 100644 --- a/src/clutils/gennode.cc +++ b/src/clutils/gennode.cc @@ -12,9 +12,8 @@ /* $Id: gennode.cc,v 3.0.1.4 1997/11/05 22:33:47 sauderd DP3.1 $ */ -#include -#include -#include +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" ////////////////////////////////////////////////////////////////////////////// // class GenericNode inline functions that depend on other classes diff --git a/src/clutils/gennodearray.cc b/src/clutils/gennodearray.cc index f78acbd14..22a9a73d3 100644 --- a/src/clutils/gennodearray.cc +++ b/src/clutils/gennodearray.cc @@ -11,12 +11,11 @@ */ -#include +#include "config.h" -#include -#include -#include -#include +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" +#include "clutils/gennodearray.h" #ifndef HAVE_MEMMOVE extern "C" { diff --git a/src/clutils/gennodelist.cc b/src/clutils/gennodelist.cc index 9560a72b1..c75d7a712 100644 --- a/src/clutils/gennodelist.cc +++ b/src/clutils/gennodelist.cc @@ -12,11 +12,10 @@ /* $Id: gennodelist.cc,v 3.0.1.2 1997/11/05 22:33:49 sauderd DP3.1 $ */ -#include -#include +#include "clutils/gennode.h" +#include "clutils/gennodelist.h" //#include -#include -#include +#include "clutils/gennodearray.h" // inserts after existNode void GenNodeList::InsertAfter( GenericNode * newNode, diff --git a/src/clutils/sc_hash.cc b/src/clutils/sc_hash.cc index 706780411..8ed4c54ab 100644 --- a/src/clutils/sc_hash.cc +++ b/src/clutils/sc_hash.cc @@ -5,11 +5,10 @@ * also, hcreate/hdestroy routines added to simulate hsearch(3). */ -#include +#include "clutils/sc_hash.h" #include #include #include -#include /* constants */ #define HASH_NULL (Hash_TableP)NULL @@ -50,6 +49,7 @@ void * SC_HASHfind( Hash_TableP t, char * s ) { e.key = s; e.symbol = 0; /* initialize to 0 - 25-Apr-1994 - kcm */ + e.type = '*'; ep = SC_HASHsearch( t, &e, HASH_FIND ); return( ep ? ep->data : 0 ); } @@ -61,9 +61,10 @@ void SC_HASHinsert( Hash_TableP t, char * s, void * data ) { e.key = s; e.data = data; e.symbol = 0; + e.type = '*'; e2 = SC_HASHsearch( t, &e, HASH_INSERT ); if( e2 ) { - fprintf( stderr, "%s: Redeclaration of %s\n", __FUNCTION__, s ); + fprintf( stderr, "%s: Redeclaration of %s\n", __func__, s ); } } @@ -258,6 +259,9 @@ struct Element * SC_HASHsearch( Hash_TableP table, const struct Element * item, /*STRINGfree(deleteme->key);*/ SC_HASH_Element_destroy( deleteme ); --table->KeyCount; + // TODO - we shouldn't be returning this pointer - it invites a + // USE_AFTER_FREE error. Could we just replace SC_HASH completely + // with one of the C++ containers? return( deleteme ); /* of course, user shouldn't deref this! */ case HASH_INSERT: /* if trying to insert it (twice), let them know */ diff --git a/src/exp2cxx/CMakeLists.txt b/src/exp2cxx/CMakeLists.txt index c50e66734..6ccebb17a 100644 --- a/src/exp2cxx/CMakeLists.txt +++ b/src/exp2cxx/CMakeLists.txt @@ -5,6 +5,7 @@ set(FEDEX_COMMON_SRCS set(exp2cxx_SOURCES ${FEDEX_COMMON_SRCS} + trace_fprintf.c fedex_main.c classes_wrapper.cc classes.c @@ -31,17 +32,13 @@ set(exp2cxx_SOURCES ) include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} ${SC_SOURCE_DIR}/include ${SC_SOURCE_DIR}/include/exppp ${SC_SOURCE_DIR}/include/express - ${SC_SOURCE_DIR}/src/base ) -SC_ADDEXEC(exp2cxx "${exp2cxx_SOURCES}" "libexppp;express;base") - -if(NOT SC_IS_SUBBUILD AND SC_GIT_VERSION) - add_dependencies(exp2cxx version_string) -endif(NOT SC_IS_SUBBUILD AND SC_GIT_VERSION) +SC_ADDEXEC(exp2cxx SOURCES ${exp2cxx_SOURCES} LINK_LIBRARIES libexppp express) if(SC_ENABLE_TESTING) add_subdirectory(test) diff --git a/src/exp2cxx/class_strings.c b/src/exp2cxx/class_strings.c index d1736a644..7058e4719 100644 --- a/src/exp2cxx/class_strings.c +++ b/src/exp2cxx/class_strings.c @@ -6,7 +6,7 @@ const char * ClassName( const char * oldname ) { int i = 0, j = 0; - static char newname [BUFSIZ]; + static char newname [BUFSIZ+1]; if( !oldname ) { return ( "" ); } @@ -152,12 +152,12 @@ const char * TYPE_get_ctype( const Type t, char * retval, size_t buf_siz ) { } const char * TYPEget_ctype( const Type t ) { - static char retval [BUFSIZ] = {0}; + static char retval [BUFSIZ+1] = {0}; return TYPE_get_ctype( t, retval, BUFSIZ ); } const char * TypeName( Type t ) { - static char name [BUFSIZ]; + static char name [BUFSIZ+1]; strcpy( name, TYPE_PREFIX ); if( TYPEget_name( t ) ) { strncat( name, FirstToUpper( TYPEget_name( t ) ), BUFSIZ - strlen( TYPE_PREFIX ) - 1 ); @@ -185,7 +185,7 @@ char ToUpper( char c ) { } const char * StrToLower( const char * word ) { - static char newword [MAX_LEN]; + static char newword [MAX_LEN+1]; int i = 0; if( !word ) { return 0; @@ -200,7 +200,7 @@ const char * StrToLower( const char * word ) { } const char * StrToUpper( const char * word ) { - static char newword [MAX_LEN]; + static char newword [MAX_LEN+1]; int i = 0; while( word [i] != '\0' ) { @@ -212,7 +212,7 @@ const char * StrToUpper( const char * word ) { } const char * StrToConstant( const char * word ) { - static char newword[MAX_LEN]; + static char newword[MAX_LEN+1]; int i = 0; while( word [i] != '\0' ) { @@ -229,7 +229,7 @@ const char * StrToConstant( const char * word ) { } const char * FirstToUpper( const char * word ) { - static char newword [MAX_LEN]; + static char newword [MAX_LEN+1]; strncpy( newword, word, MAX_LEN ); newword[0] = ToUpper( newword[0] ); diff --git a/src/exp2cxx/classes.c b/src/exp2cxx/classes.c index 4f5a8561e..40dcf46c2 100644 --- a/src/exp2cxx/classes.c +++ b/src/exp2cxx/classes.c @@ -25,14 +25,12 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7. /* this is used to add new dictionary calls */ /* #define NEWDICT */ -#include #include #include -#include #include "classes.h" #include -#include +#include "./trace_fprintf.h" int multiple_inheritance = 1; int print_logging = 0; @@ -96,7 +94,7 @@ void format_for_std_stringout( FILE * f, char * orig_buf ) { optr++; } fprintf( f, "%s", s_end ); - sc_free( orig_buf ); + free( orig_buf ); } void USEREFout( Schema schema, Dictionary refdict, Linked_List reflist, char * type, FILE * file ) { @@ -104,8 +102,8 @@ void USEREFout( Schema schema, Dictionary refdict, Linked_List reflist, char * t DictionaryEntry de; struct Rename * r; Linked_List list; - char td_name[BUFSIZ]; - char sch_name[BUFSIZ]; + char td_name[BUFSIZ+1]; + char sch_name[BUFSIZ+1]; strncpy( sch_name, PrettyTmpName( SCHEMAget_name( schema ) ), BUFSIZ ); @@ -135,10 +133,9 @@ void USEREFout( Schema schema, Dictionary refdict, Linked_List reflist, char * t wlist = ( Linked_List )DICTlookup( dict, r->schema->symbol.name ); if( !wlist ) { wlist = LISTcreate(); - DICTdefine( dict, r->schema->symbol.name, ( Generic ) wlist, - ( Symbol * )0, OBJ_UNKNOWN ); + DICTdefine( dict, r->schema->symbol.name, wlist, NULL, OBJ_UNKNOWN ); } - LISTadd_last( wlist, ( Generic ) r ); + LISTadd_last( wlist, r ); } /* step 2: for each list, print out the renames */ diff --git a/src/exp2cxx/classes.h b/src/exp2cxx/classes.h index e6dd63c01..462e22687 100644 --- a/src/exp2cxx/classes.h +++ b/src/exp2cxx/classes.h @@ -76,7 +76,7 @@ typedef struct file_holder { } File_holder, FILES; /** these fields are used so that ENTITY types are processed in order - * when appearing in differnt schemas + * when appearing in different schemas */ typedef struct EntityTag_ * EntityTag; struct EntityTag_ { diff --git a/src/exp2cxx/classes_attribute.c b/src/exp2cxx/classes_attribute.c index faf12e480..cf2de189d 100644 --- a/src/exp2cxx/classes_attribute.c +++ b/src/exp2cxx/classes_attribute.c @@ -10,21 +10,15 @@ The conventions used in this binding follow the proposed specification for the STEP Standard Data Access Interface as defined in document N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7. *******************************************************************/ -#include #include #include #include -#include #include #include #include "classes.h" #include "classes_attribute.h" -#include - -#if defined( _WIN32 ) || defined ( __WIN32__ ) -# define snprintf _snprintf -#endif +#include "./trace_fprintf.h" extern int old_accessors; extern int print_logging; @@ -63,7 +57,7 @@ char * generate_attribute_name( Variable a, char * out ) { } } *q = '\0'; - sc_free( temp ); + free( temp ); return out; } @@ -101,7 +95,7 @@ bool attrIsObj( Type t ) { * \p attr_count_tmp is a _copy_ of attr_count */ void ATTRnames_print( Entity entity, FILE* file ) { - char attrnm [BUFSIZ]; + char attrnm [BUFSIZ+1]; LISTdo( ENTITYget_attributes( entity ), v, Variable ) { generate_attribute_name( v, attrnm ); @@ -120,7 +114,7 @@ void ATTRnames_print( Entity entity, FILE* file ) { * \param file file being written to */ void DataMemberPrintAttr( Entity entity, Variable a, FILE * file ) { - char attrnm [BUFSIZ]; + char attrnm [BUFSIZ+1]; const char * ctype, * etype; if( !VARget_inverse( a ) && ( VARget_initializer( a ) == EXPRESSION_NULL ) ) { ctype = TYPEget_ctype( VARget_type( a ) ); @@ -129,11 +123,24 @@ void DataMemberPrintAttr( Entity entity, Variable a, FILE * file ) { fprintf( stderr, "Warning: in entity %s, the type for attribute %s is not fully implemented\n", ENTITYget_name( entity ), attrnm ); } if( TYPEis_entity( VARget_type( a ) ) ) { - fprintf( file, " SDAI_Application_instance_ptr _%s;", attrnm ); + fprintf( file, " SDAI_Application_instance_ptr _%s = NULL;", attrnm ); } else if( TYPEis_aggregate( VARget_type( a ) ) ) { - fprintf( file, " %s_ptr _%s;", ctype, attrnm ); + fprintf( file, " %s_ptr _%s = NULL;", ctype, attrnm ); } else { - fprintf( file, " %s _%s;", ctype, attrnm ); + Class_Of_Type class = TYPEget_type(VARget_type(a)); + switch (class) { + case boolean_: + fprintf(file, " %s _%s = false;", ctype, attrnm); + break; + case integer_: + fprintf(file, " %s _%s = 0;", ctype, attrnm); + break; + case real_: + fprintf(file, " %s _%s = 0.0;", ctype, attrnm); + break; + default: + fprintf(file, " %s _%s;", ctype, attrnm); + } } if( VARget_optional( a ) ) { fprintf( file, " // OPTIONAL" ); @@ -164,8 +171,8 @@ void DataMemberPrintAttr( Entity entity, Variable a, FILE * file ) { void ATTRsign_access_methods( Variable a, FILE * file ) { Type t = VARget_type( a ); - char ctype [BUFSIZ]; - char attrnm [BUFSIZ]; + char ctype [BUFSIZ+1]; + char attrnm [BUFSIZ+1]; generate_attribute_func_name( a, attrnm ); @@ -207,8 +214,8 @@ void ATTRsign_access_methods( Variable a, FILE * file ) { ******************************************************************/ void ATTRprint_access_methods_get_head( const char * classnm, Variable a, FILE * file, bool returnsConst ) { Type t = VARget_type( a ); - char ctype [BUFSIZ]; /* return type of the get function */ - char funcnm [BUFSIZ]; /* name of member function */ + char ctype [BUFSIZ+1]; /* return type of the get function */ + char funcnm [BUFSIZ+1]; /* name of member function */ generate_attribute_func_name( a, funcnm ); strncpy( ctype, AccessType( t ), BUFSIZ ); ctype[BUFSIZ-1] = '\0'; @@ -239,8 +246,8 @@ void ATTRprint_access_methods_get_head( const char * classnm, Variable a, FILE * void ATTRprint_access_methods_put_head( const char * entnm, Variable a, FILE * file ) { Type t = VARget_type( a ); - char ctype [BUFSIZ]; - char funcnm [BUFSIZ]; + char ctype [BUFSIZ+1]; + char funcnm [BUFSIZ+1]; generate_attribute_func_name( a, funcnm ); @@ -441,7 +448,7 @@ void ATTRprint_access_methods_log_bool( const char * entnm, const char * attrnm, /** print access methods for inverse attrs, using iAMap */ void INVprint_access_methods( const char * entnm, const char * attrnm, const char * funcnm, const char * nm, const char * ctype, Variable a, FILE * file, Schema schema ) { - char iaName[BUFSIZ] = {0}; + char iaName[BUFSIZ+1] = {0}; snprintf( iaName, BUFSIZ - 1, "%s::%s%d%s%s", SCHEMAget_name( schema ), ATTR_PREFIX, a->idx, /* can it ever be anything but "I"? */ ( VARis_derived( a ) ? "D" : ( VARis_type_shifter( a ) ? "R" : ( VARget_inverse( a ) ? "I" : "" ) ) ), attrnm ); @@ -489,12 +496,12 @@ void INVprint_access_methods( const char * entnm, const char * attrnm, const cha void ATTRprint_access_methods( const char * entnm, Variable a, FILE * file, Schema schema ) { Type t = VARget_type( a ); Class_Of_Type classType; - char ctype [BUFSIZ]; /* type of data member */ - char attrnm [BUFSIZ]; - char membernm[BUFSIZ]; - char funcnm [BUFSIZ]; /* name of member function */ + char ctype [BUFSIZ+1]; /* type of data member */ + char attrnm [BUFSIZ+1]; + char membernm[BUFSIZ+1]; + char funcnm [BUFSIZ+1]; /* name of member function */ - char nm [BUFSIZ]; + char nm [BUFSIZ+1]; /* I believe nm has the name of the underlying type without Sdai in front of it */ if( TYPEget_name( t ) ) { strncpy( nm, FirstToUpper( TYPEget_name( t ) ), BUFSIZ - 1 ); diff --git a/src/exp2cxx/classes_entity.c b/src/exp2cxx/classes_entity.c index 9af9c3ec4..39e69c8a1 100644 --- a/src/exp2cxx/classes_entity.c +++ b/src/exp2cxx/classes_entity.c @@ -14,11 +14,16 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7. /* this is used to add new dictionary calls */ /* #define NEWDICT */ -#include +#define _XOPEN_SOURCE /* for S_IFDIR */ +#include +#include +#include +#ifdef _WIN32 +# include +#endif /* _WIN32 */ #include -#include +#include #include -#include #include "classes.h" #include "classes_entity.h" #include "class_strings.h" @@ -26,11 +31,34 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7. #include #include "rules.h" -#include +#include "./trace_fprintf.h" extern int multiple_inheritance; extern int old_accessors; +/* cross-platform mkdir */ +static 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 */ +static 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; +} + /* attribute numbering used to use a global variable attr_count. * it could be tricky keep the numbering consistent when making * changes, so this has been replaced with an added member in the @@ -59,7 +87,7 @@ void ENTITYnames_print( Entity entity, FILE * file ) { * \param schema schema being processed */ void LIBdescribe_entity( Entity entity, FILE * file, Schema schema ) { - char attrnm [BUFSIZ]; + char attrnm [BUFSIZ+1]; fprintf( file, "EntityDescriptor * %s::%s%s = 0;\n", SCHEMAget_name( schema ), ENT_PREFIX, ENTITYget_name( entity ) ); LISTdo( ENTITYget_attributes( entity ), v, Variable ) { @@ -81,7 +109,7 @@ void LIBdescribe_entity( Entity entity, FILE * file, Schema schema ) { void LIBmemberFunctionPrint( Entity entity, Linked_List neededAttr, FILE * file, Schema schema ) { Linked_List attr_list; - char entnm [BUFSIZ]; + char entnm [BUFSIZ+1]; strncpy( entnm, ENTITYget_classname( entity ), BUFSIZ ); /* assign entnm */ @@ -149,7 +177,7 @@ int get_attribute_number( Entity entity ) { * \p file file being written to */ void ENTITYhead_print( Entity entity, FILE * file ) { - char entnm [BUFSIZ]; + char entnm [BUFSIZ+1]; Linked_List list; Entity super = 0; @@ -180,7 +208,7 @@ void ENTITYhead_print( Entity entity, FILE * file ) { * skip inverse attrs */ void DataMemberInit( bool * first, Variable a, FILE * lib ) { - char attrnm [BUFSIZ]; + char attrnm [BUFSIZ+1]; if( VARis_derived( a ) || VARget_inverse( a ) ) { return; } @@ -244,7 +272,7 @@ void MemberFunctionSign( Entity entity, Linked_List neededAttr, FILE * file ) { Linked_List attr_list; static int entcode = 0; - char entnm [BUFSIZ]; + char entnm [BUFSIZ+1]; strncpy( entnm, ENTITYget_classname( entity ), BUFSIZ ); /* assign entnm */ entnm[BUFSIZ-1] = '\0'; @@ -328,7 +356,7 @@ void initializeAttrs( Entity e, FILE* file ) { void LIBstructor_print( Entity entity, Linked_List neededAttr, FILE * file, Schema schema ) { Linked_List attr_list; Type t; - char attrnm [BUFSIZ]; + char attrnm [BUFSIZ+1]; Linked_List list; Entity principalSuper = 0; @@ -489,13 +517,13 @@ void LIBstructor_print( Entity entity, Linked_List neededAttr, FILE * file, Sche void LIBstructor_print_w_args( Entity entity, Linked_List neededAttr, FILE * file, Schema schema ) { Linked_List attr_list; Type t; - char attrnm [BUFSIZ]; + char attrnm [BUFSIZ+1]; Linked_List list; int super_cnt = 0; /* added for calling parents constructor if there is one */ - char parentnm [BUFSIZ]; + char parentnm [BUFSIZ+1]; char * parent = 0; const char * entnm; @@ -599,8 +627,8 @@ void LIBstructor_print_w_args( Entity entity, Linked_List neededAttr, FILE * fil fprintf( file, " /* Put attribute on this class' attributes list so the access functions still work. */\n" ); fprintf( file, " attributes.push( a );\n" ); - fprintf( file, " /* Put attribute on the attributes list for the main inheritance heirarchy. **\n" ); - fprintf( file, " ** The push method rejects duplicates found by comparing attrDescriptor's. */\n" ); + fprintf( file, " /* Put attribute on the attributes list for the main inheritance hierarchy. */\n" ); + fprintf( file, " /* The push method rejects duplicates found by comparing attrDescriptor's. */\n" ); fprintf( file, " if( addAttrs ) {\n" ); fprintf( file, " se->attributes.push( a );\n }\n" ); @@ -676,7 +704,7 @@ char * generate_dict_attr_name( Variable a, char * out ) { } *q = '\0'; - sc_free( temp ); + free( temp ); return out; } @@ -690,8 +718,8 @@ char * generate_dict_attr_name( Variable a, char * out ) { void ENTITYincode_print( Entity entity, FILE * header, FILE * impl, Schema schema ) { #define entity_name ENTITYget_name(entity) #define schema_name SCHEMAget_name(schema) - char attrnm [BUFSIZ]; - char dict_attrnm [BUFSIZ]; + char attrnm [BUFSIZ+1]; + char dict_attrnm [BUFSIZ+1]; const char * super_schema; char * tmp, *tmp2; bool hasInverse = false; @@ -827,7 +855,7 @@ void ENTITYincode_print( Entity entity, FILE * header, FILE * impl, Schema schem ); } else { /* manufacture new one(s) on the spot */ - char typename_buf[MAX_LEN]; + char typename_buf[MAX_LEN+1]; print_typechain( header, impl, v->type, typename_buf, schema, v->name->symbol.name ); fprintf( impl, " %s::%s%d%s%s =\n new %s" "(\"%s\",%s,%s,%s%s,\n *%s::%s%s);\n", @@ -864,15 +892,15 @@ void ENTITYincode_print( Entity entity, FILE * header, FILE * impl, Schema schem if( VARis_derived( v ) && v->initializer ) { tmp = EXPRto_string( v->initializer ); - tmp2 = ( char * )sc_malloc( sizeof( char ) * ( strlen( tmp ) + BUFSIZ ) ); + tmp2 = ( char * )malloc( sizeof( char ) * ( strlen( tmp ) + BUFSIZ ) ); fprintf( impl, " %s::%s%d%s%s->initializer_(\"%s\");\n", schema_name, ATTR_PREFIX, v->idx, ( VARis_derived( v ) ? "D" : ( VARis_type_shifter( v ) ? "R" : ( VARget_inverse( v ) ? "I" : "" ) ) ), attrnm, format_for_stringout( tmp, tmp2 ) ); - sc_free( tmp ); - sc_free( tmp2 ); + free( tmp ); + free( tmp2 ); } if( VARget_inverse( v ) ) { fprintf( impl, " %s::%s%d%s%s->inverted_attr_id_(\"%s\");\n", @@ -957,7 +985,6 @@ void ENTITYPrint_cc( const Entity entity, FILE * createall, FILE * header, FILE DEBUG( "Entering ENTITYPrint_cc for %s\n", name ); fprintf( impl, "#include \"schema.h\"\n" ); - fprintf( impl, "#include \"sc_memmgr.h\"\n" ); fprintf( impl, "#include \"entity/%s.h\"\n\n", name ); LIBdescribe_entity( entity, impl, schema ); @@ -1007,14 +1034,14 @@ static void collectAttributes( Linked_List curList, const Entity curEntity, enum } /* prepend this entity's attributes to the result list */ LISTdo( ENTITYget_attributes( curEntity ), attr, Variable ) { - LISTadd_first( curList, ( Generic ) attr ); + LISTadd_first( curList, attr ); } LISTod; } static bool listContainsVar( Linked_List l, Variable v ) { const char * vName = VARget_simple_name( v ); LISTdo( l, curr, Variable ) { - if( streq( vName, VARget_simple_name( curr ) ) ) { + if( !strcmp( vName, VARget_simple_name( curr ) ) ) { return true; } } @@ -1065,12 +1092,12 @@ void ENTITYPrint( Entity entity, FILES * files, Schema schema, bool externMap ) /* create list of attr that have to be inherited in EXPRESS */ collectAttributes( required, entity, ALL_BUT_FIRST ); - /* build list of unique attr that are required but havn't been */ + /* build list of unique attr that are required but haven't been */ /* inherited */ LISTdo( required, attr, Variable ) { if( !listContainsVar( existing, attr ) && !listContainsVar( remaining, attr ) ) { - LISTadd_first( remaining, ( Generic ) attr ); + LISTadd_first( remaining, attr ); } } LISTod; diff --git a/src/exp2cxx/classes_misc.c b/src/exp2cxx/classes_misc.c index c30b37583..9db5e7eb7 100644 --- a/src/exp2cxx/classes_misc.c +++ b/src/exp2cxx/classes_misc.c @@ -1,10 +1,7 @@ #define CLASSES_MISC_C -#include #include #include "classes.h" -#include -#include "sc_version_string.h" #include "class_strings.h" /** \file classes_misc.c @@ -44,7 +41,7 @@ FILE * FILEcreate( const char * filename ) { fprintf( file, "#ifndef %s\n", fn ); fprintf( file, "#define %s\n\n", fn ); - fprintf( file, "// This file was generated by exp2cxx,\n// %s.\n", sc_version ); + fprintf( file, "// This file was generated by exp2cxx,\n// %s.\n", SC_VERSION ); fprintf( file, "// You probably don't want to edit it since your modifications\n" ); fprintf( file, "// will be lost if exp2cxx is used to regenerate it.\n\n" ); return ( file ); @@ -71,7 +68,7 @@ int isAggregateType( const Type t ) { /** \returns a pointer to a static buffer, containing a string which is the type used by the c++ data member access functions */ const char * AccessType( Type t ) { Class_Of_Type class; - static char nm [BUFSIZ]; + static char nm [BUFSIZ+1]; strncpy( nm, TypeName( t ), BUFSIZ - 4 ); if( TYPEis_entity( t ) ) { strcat( nm, "_ptr" ); @@ -103,7 +100,7 @@ const char * AccessType( Type t ) { */ const char * PrettyTmpName( const char * oldname ) { int i = 0; - static char newname [BUFSIZ]; + static char newname [BUFSIZ+1]; newname [0] = '\0'; while( ( oldname [i] != '\0' ) && ( i < BUFSIZ ) ) { newname [i] = ToLower( oldname [i] ); @@ -124,7 +121,7 @@ const char * PrettyTmpName( const char * oldname ) { /* This function is out of date DAS */ const char * EnumName( const char * oldname ) { int j = 0; - static char newname [MAX_LEN]; + static char newname [MAX_LEN+1]; if( !oldname ) { return ( "" ); } @@ -140,7 +137,7 @@ const char * EnumName( const char * oldname ) { const char * SelectName( const char * oldname ) { int j = 0; - static char newname [MAX_LEN]; + static char newname [MAX_LEN+1]; if( !oldname ) { return ( "" ); } @@ -204,7 +201,7 @@ const char * FundamentalType( const Type t, int report_reftypes ) { * TypeDescriptor or subtype of TypeDescriptor to represent Type t in the dictionary. */ const char * TypeDescriptorName( Type t ) { - static char b [BUFSIZ]; + static char b [BUFSIZ+1]; Schema parent = t->superscope; /* NOTE - I corrected a prev bug here in which the *current* schema was ** passed to this function. Now we take "parent" - the schema in which @@ -323,7 +320,7 @@ Entity ENTITYput_superclass( Entity entity ) { LISTod; } - tag = ( EntityTag ) sc_malloc( sizeof( struct EntityTag_ ) ); + tag = ( EntityTag ) malloc( sizeof( struct EntityTag_ ) ); tag -> superclass = super; TYPEput_clientData( ENTITYget_type( entity ), ( ClientData ) tag ); return super; @@ -340,7 +337,7 @@ Entity ENTITYget_superclass( Entity entity ) { void ENTITYget_first_attribs( Entity entity, Linked_List result ) { Linked_List supers; - LISTdo( ENTITYget_attributes( entity ), attr, Generic ) + LISTdo( ENTITYget_attributes( entity ), attr, void * ) LISTadd_last( result, attr ); LISTod; supers = ENTITYget_supertypes( entity ); @@ -387,10 +384,10 @@ Variable VARis_type_shifter( Variable a ) { temp = EXPRto_string( VARget_name( a ) ); if( ! strncmp( StrToLower( temp ), "self\\", 5 ) ) { /* a is a type shifter */ - sc_free( temp ); + free( temp ); return a; } - sc_free( temp ); + free( temp ); return 0; } diff --git a/src/exp2cxx/classes_type.c b/src/exp2cxx/classes_type.c index 20a850935..bce1d34fb 100644 --- a/src/exp2cxx/classes_type.c +++ b/src/exp2cxx/classes_type.c @@ -14,18 +14,24 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7. /* this is used to add new dictionary calls */ /* #define NEWDICT */ -#include -#include +#define _XOPEN_SOURCE /* for S_IFDIR */ +#include +#include +#include +#ifdef _WIN32 +# include +#endif /* _WIN32 */ + #include +#include #include -#include #include "classes.h" #include "class_strings.h" #include "genCxxFilenames.h" #include #include "rules.h" -#include +#include "./trace_fprintf.h" static int type_count; /**< number each temporary type for same reason as \sa attr_count */ @@ -43,6 +49,59 @@ int isMultiDimAggregateType( const Type t ); void Type_Description( const Type, char * ); void TypeBody_Description( TypeBody body, char * buf ); +/* cross-platform mkdir */ +static 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 */ +static 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; +} + +#ifdef _WIN32 +/* for windows, rewrite backslashes in paths + * that will be written to generated code + */ +static const char * path2str_fn( const char * fileMacro ) { + static char * result = 0; + static size_t rlen = 0; + char * p; + if( rlen < strlen( fileMacro ) ) { + if( result ) { + free( result ); + } + rlen = strlen( fileMacro ); + result = ( char * )malloc( rlen * sizeof( char ) + 1 ); + } + strcpy( result, fileMacro ); + p = result; + while( *p ) { + if( *p == '\\' ) { + *p = '/'; + } + p++; + } + return result; +} +# define path2str(path) path2str_fn(path) +#else +# define path2str(path) path +#endif + /** write representation of expression to end of buf * * TODO: add buflen arg and check for overflow @@ -94,23 +153,22 @@ void strcat_bounds( TypeBody b, char * buf ) { ** Description: prints code to represent an enumerated type in c++ ** Side Effects: prints to header file ** Status: ok 1/15/91 - ** Changes: Modified to check for appropiate key words as described + ** Changes: Modified to check for appropriate key words as described ** in "SDAI C++ Binding for PDES, Inc. Prototyping" by ** Stephen Clark. ** - Changed to match CD2 Part 23, 1/14/97 DAS ** Change Date: 5/22/91 CD ******************************************************************/ const char * EnumCElementName( Type type, Expression expr ) { - static char buf [BUFSIZ]; + static char buf [BUFSIZ+1]; sprintf( buf, "%s__", EnumName( TYPEget_name( type ) ) ); - strcat( buf, StrToLower( EXPget_name( expr ) ) ); - + strncat( buf, StrToLower( EXPget_name( expr ) ), BUFSIZ ); return buf; } char * CheckEnumSymbol( char * s ) { - static char b [BUFSIZ]; + static char b [BUFSIZ+1]; if( strcmp( s, "sdaiTRUE" ) && strcmp( s, "sdaiFALSE" ) && strcmp( s, "sdaiUNKNOWN" ) ) { @@ -120,7 +178,7 @@ char * CheckEnumSymbol( char * s ) { } else { strcpy( b, s ); strcat( b, "_" ); - fprintf( stderr, "Warning in %s: the enumerated value %s is already being used and has been changed to %s\n", __FUNCTION__, s, b ); + fprintf( stderr, "Warning in %s: the enumerated value %s is already being used and has been changed to %s\n", __func__, s, b ); return ( b ); } } @@ -153,8 +211,8 @@ char * TypeDescription( const Type t ) { void TYPEenum_inc_print( const Type type, FILE * inc ) { Expression expr; - char tdnm[BUFSIZ], - enumAggrNm[BUFSIZ]; + char tdnm[BUFSIZ+1], + enumAggrNm[BUFSIZ+1]; const char * n; /* pointer to class name */ int cnt = 0; @@ -182,12 +240,12 @@ void TYPEenum_inc_print( const Type type, FILE * inc ) { /* constructors */ strncpy( tdnm, TYPEtd_name( type ), BUFSIZ ); - tdnm[BUFSIZ-1] = '\0'; - fprintf( inc, " public:\n %s (const char * n =0, Enum" - "TypeDescriptor *et =%s);\n", n, tdnm ); + tdnm[BUFSIZ - 1] = '\0'; + fprintf( inc, " public:\n %s (const char * n =0, EnumTypeDescriptor *et =%s);\n", n, tdnm ); fprintf( inc, " %s (%s e, EnumTypeDescriptor *et =%s)\n" " : type(et) { set_value (e); }\n", n, EnumName( TYPEget_name( type ) ), tdnm ); + fprintf( inc, " %s (const %s &e) { set_value(e); }\n", n, TYPEget_ctype( type ) ); /* destructor */ fprintf( inc, " ~%s () { }\n", n ); @@ -250,7 +308,7 @@ void TYPEenum_lib_print( const Type type, FILE * f ) { DictionaryEntry de; Expression expr; const char * n; /* pointer to class name */ - char c_enum_ele [BUFSIZ]; + char c_enum_ele [BUFSIZ+1]; n = TYPEget_ctype( type ); @@ -318,7 +376,6 @@ void TYPEPrint_cc( const Type type, const filenames_t * names, FILE * hdr, FILE DEBUG( "Entering TYPEPrint_cc for %s\n", names->impl ); fprintf( impl, "#include \"schema.h\"\n" ); - fprintf( impl, "#include \"sc_memmgr.h\"\n" ); fprintf( impl, "#include \"%s\"\n\n", names->header ); if ( TYPEis_enumeration( type ) ) { @@ -380,7 +437,7 @@ static void printEnumCreateHdr( FILE * inc, const Type type ) { /** See header comment above by printEnumCreateHdr. */ static void printEnumCreateBody( FILE * lib, const Type type ) { const char * nm = TYPEget_ctype( type ); - char tdnm[BUFSIZ]; + char tdnm[BUFSIZ+1]; tdnm[BUFSIZ-1] = '\0'; strncpy( tdnm, TYPEtd_name( type ), BUFSIZ ); @@ -399,7 +456,7 @@ static void printEnumAggrCrHdr( FILE * inc, const Type type ) { static void printEnumAggrCrBody( FILE * lib, const Type type ) { const char * n = TYPEget_ctype( type ); - char tdnm[BUFSIZ]; + char tdnm[BUFSIZ+1]; strncpy( tdnm, TYPEtd_name( type ), BUFSIZ ); tdnm[BUFSIZ-1] = '\0'; @@ -424,7 +481,7 @@ static void printEnumAggrCrBody( FILE * lib, const Type type ) { ** Dec 2011 - MAP - remove goto **************************************************************************/ void TYPEprint_typedefs( Type t, FILE * classes ) { - char nm [BUFSIZ]; + char nm [BUFSIZ+1]; Type i; bool aggrNot1d = true; /* added so I can get rid of a goto */ @@ -492,10 +549,8 @@ void TYPEprint_typedefs( Type t, FILE * classes ) { } /* Print the extern statement: */ -#if !defined(__BORLAND__) strncpy( nm, TYPEtd_name( t ), BUFSIZ ); fprintf( classes, "extern SC_SCHEMA_EXPORT %s *%s;\n", GetTypeDescriptorName( t ), nm ); -#endif } /** ** @@ -508,10 +563,10 @@ void TYPEprint_typedefs( Type t, FILE * classes ) { TYPEprint_init() (below) which is done in exp2cxx's 1st pass only.) *****/ void TYPEprint_descriptions( const Type type, FILES * files, Schema schema ) { - char tdnm [BUFSIZ], - typename_buf [MAX_LEN], - base [BUFSIZ], - nm [BUFSIZ]; + char tdnm [BUFSIZ+1], + typename_buf [MAX_LEN+1], + base [BUFSIZ+1], + nm [BUFSIZ+1]; Type i; strncpy( tdnm, TYPEtd_name( type ), BUFSIZ ); @@ -565,8 +620,8 @@ void TYPEprint_descriptions( const Type type, FILES * files, Schema schema ) { } void TYPEprint_init( const Type type, FILE * header, FILE * impl, Schema schema ) { - char tdnm [BUFSIZ]; - char typename_buf[MAX_LEN]; + char tdnm [BUFSIZ+1]; + char typename_buf[MAX_LEN+1]; strncpy( tdnm, TYPEtd_name( type ), BUFSIZ ); @@ -637,7 +692,7 @@ void TYPEprint_new( const Type type, FILE * create, Schema schema, bool needWR ) char * temp; temp = non_unique_types_string( type ); fprintf( create, " %s = new SelectTypeDescriptor (\n ~%s, //unique elements,\n", TYPEtd_name( type ), temp ); - sc_free( temp ); + free( temp ); TYPEprint_nm_ft_desc( schema, type, create, "," ); fprintf( create, " (SelectCreator) create_%s); // Creator function\n", SelectName( TYPEget_name( type ) ) ); } else { @@ -834,7 +889,7 @@ void print_typechain( FILE * header, FILE * impl, const Type t, char * buf, Sche const char * ctype = TYPEget_ctype( t ); int count = type_count++; - char name_buf[MAX_LEN]; + char name_buf[MAX_LEN+1]; int s; switch( TYPEget_body( t )->type ) { @@ -880,7 +935,7 @@ void print_typechain( FILE * header, FILE * impl, const Type t, char * buf, Sche } else { Type base = 0; /* no name, recurse */ - char callee_buffer[MAX_LEN]; + char callee_buffer[MAX_LEN+1]; if( TYPEget_body( t ) ) { base = TYPEget_body( t )->base; } @@ -1028,10 +1083,10 @@ void TypeBody_Description( TypeBody body, char * buf ) { } const char * IdlEntityTypeName( Type t ) { - static char name [BUFSIZ]; - strcpy( name, TYPE_PREFIX ); + static char name [BUFSIZ+1]; + strncpy( name, TYPE_PREFIX, BUFSIZ ); if( TYPEget_name( t ) ) { - strcpy( name, FirstToUpper( TYPEget_name( t ) ) ); + strncpy( name, FirstToUpper( TYPEget_name( t ) ), BUFSIZ ); } else { return TYPEget_ctype( t ); } @@ -1041,7 +1096,7 @@ const char * IdlEntityTypeName( Type t ) { const char * GetAggrElemType( const Type type ) { Class_Of_Type class; Type bt; - static char retval [BUFSIZ]; + static char retval [BUFSIZ+1]; if( isAggregateType( type ) ) { bt = TYPEget_nonaggregate_base_type( type ); @@ -1064,14 +1119,14 @@ const char * GetAggrElemType( const Type type ) { /* case TYPE_ENTITY: */ if( class == entity_ ) { - strcpy( retval, IdlEntityTypeName( bt ) ); + strncpy( retval, IdlEntityTypeName( bt ), BUFSIZ ); } /* case TYPE_ENUM: */ /* case TYPE_SELECT: */ if( ( class == enumeration_ ) || ( class == select_ ) ) { - strcpy( retval, TYPEget_ctype( bt ) ); + strncpy( retval, TYPEget_ctype( bt ), BUFSIZ ); } /* case TYPE_LOGICAL: */ @@ -1099,7 +1154,7 @@ const char * GetAggrElemType( const Type type ) { const char * TYPEget_idl_type( const Type t ) { Class_Of_Type class; - static char retval [BUFSIZ]; + static char retval [BUFSIZ+1]; /* aggregates are based on their base type case TYPE_ARRAY: @@ -1168,18 +1223,14 @@ const char * TYPEget_idl_type( const Type t ) { /* case TYPE_ENTITY: */ if( class == entity_ ) { /* better do this because the return type might go away */ - strcpy( retval, IdlEntityTypeName( t ) ); + strncpy( retval, IdlEntityTypeName( t ), BUFSIZ - 4 ); strcat( retval, "_ptr" ); return retval; } /* case TYPE_ENUM: */ /* case TYPE_SELECT: */ if( class == enumeration_ ) { - strncpy( retval, EnumName( TYPEget_name( t ) ), BUFSIZ - 2 ); - - strcat( retval, " /*" ); - strcat( retval, IdlEntityTypeName( t ) ); - strcat( retval, "*/ " ); + snprintf( retval, BUFSIZ, "%s /*%s*/ ", EnumName(TYPEget_name(t)), IdlEntityTypeName(t) ); return retval; } if( class == select_ ) { @@ -1204,9 +1255,8 @@ const char * TYPEget_idl_type( const Type t ) { char * TYPEget_express_type( const Type t ) { Class_Of_Type class; Type bt; - char retval [BUFSIZ]; - char * n, * permval, * aggr_type; - + char retval [BUFSIZ+1] = {'\0'}; + char * n = NULL, * permval = NULL, * aggr_type = NULL; /* 1. "DEFINED" types */ /* case TYPE_ENUM: */ @@ -1279,7 +1329,7 @@ char * TYPEget_express_type( const Type t ) { /* this will declare extra memory when aggregate is > 1D */ - permval = ( char * )sc_malloc( strlen( retval ) * sizeof( char ) + 1 ); + permval = ( char * )malloc( strlen( retval ) * sizeof( char ) + 1 ); strcpy( permval, retval ); return permval; @@ -1287,7 +1337,7 @@ char * TYPEget_express_type( const Type t ) { /* default returns undefined */ - fprintf( stderr, "Warning in %s: type %s is undefined\n", __FUNCTION__, TYPEget_name( t ) ); + fprintf( stderr, "Warning in %s: type %s is undefined\n", __func__, TYPEget_name( t ) ); return ( "SCLundefined" ); } @@ -1296,7 +1346,9 @@ char * TYPEget_express_type( const Type t ) { void AGGRprint_bound( FILE * header, FILE * impl, const char * var_name, const char * aggr_name, const char * cname, Expression bound, int boundNr ) { if( bound->symbol.resolved ) { if( bound->type == Type_Funcall ) { - fprintf( impl, " %s->SetBound%dFromExpressFuncall( \"%s\" );\n", var_name, boundNr, EXPRto_string( bound ) ); + char *bound_str = EXPRto_string(bound); + fprintf( impl, " %s->SetBound%dFromExpressFuncall( \"%s\" );\n", var_name, boundNr, bound_str ); + free(bound_str); } else { fprintf( impl, " %s->SetBound%d( %d );\n", var_name, boundNr, bound->u.integer ); } diff --git a/src/exp2cxx/classes_wrapper.cc b/src/exp2cxx/classes_wrapper.cc index 1c7e39b5e..ef874a790 100644 --- a/src/exp2cxx/classes_wrapper.cc +++ b/src/exp2cxx/classes_wrapper.cc @@ -4,9 +4,8 @@ #include "complexSupport.h" #include "class_strings.h" -#include -#include +#include "./trace_fprintf.h" /******************************************************************* ** FedEx parser output module for generating C++ class definitions @@ -62,28 +61,26 @@ void print_file_header( FILES * files ) { files -> incall = FILEcreate( "schema.h" ); fprintf( files->incall, "\n// in the exp2cxx source code, this file is generally referred to as files->incall or schemafile\n" ); - fprintf( files->incall, "\n#ifndef SC_%s_EXPORT\n", "SCHEMA" ); - fprintf( files->incall, "# if defined(SC_%s_DLL_EXPORTS) && defined(SC_%s_DLL_IMPORTS)\n", "SCHEMA", "SCHEMA" ); - fprintf( files->incall, "# error \"SC_%s_DLL_EXPORTS or SC_%s_DLL_IMPORTS can be defined, not both.\"\n", "SCHEMA", "SCHEMA" ); - fprintf( files->incall, "# elif defined(SC_%s_DLL_EXPORTS)\n", "SCHEMA" ); - fprintf( files->incall, "# define SC_%s_EXPORT __declspec(dllexport)\n", "SCHEMA" ); - fprintf( files->incall, "# elif defined(SC_%s_DLL_IMPORTS)\n", "SCHEMA" ); - fprintf( files->incall, "# define SC_%s_EXPORT __declspec(dllimport)\n", "SCHEMA" ); + fprintf( files->incall, "\n#if !defined(SC_STATIC) && defined(_WIN32)\n" ); + fprintf( files->incall, "# if defined(SC_SCHEMA_DLL_EXPORTS)\n" ); + fprintf( files->incall, "# define SC_SCHEMA_EXPORT __declspec(dllexport)\n" ); fprintf( files->incall, "# else\n" ); - fprintf( files->incall, "# define SC_%s_EXPORT\n", "SCHEMA" ); + fprintf( files->incall, "# define SC_SCHEMA_EXPORT __declspec(dllimport)\n" ); fprintf( files->incall, "# endif\n" ); + fprintf( files->incall, "#else\n" ); + fprintf( files->incall, "# define SC_SCHEMA_EXPORT\n" ); fprintf( files->incall, "#endif\n\n" ); fprintf( files->incall, "#ifdef SC_LOGGING\n" ); fprintf( files->incall, "#include \n" ); fprintf( files->incall, "#endif\n" ); - fprintf( files->incall, "#include \n\n" ); - fprintf( files->incall, "\n#include \n" ); - fprintf( files->incall, "\n#include \n" ); - fprintf( files->incall, "\n#include \n" ); - fprintf( files->incall, "\n#include \n" ); - fprintf( files->incall, "\n#include \n" ); + fprintf( files->incall, "#include \"clstepcore/sdai.h\"\n\n" ); + fprintf( files->incall, "\n#include \"clstepcore/Registry.h\"\n" ); + fprintf( files->incall, "\n#include \"clstepcore/STEPaggregate.h\"\n" ); + fprintf( files->incall, "\n#include \"clstepcore/STEPundefined.h\"\n" ); + fprintf( files->incall, "\n#include \"clstepcore/ExpDict.h\"\n" ); + fprintf( files->incall, "\n#include \"clstepcore/STEPattribute.h\"\n" ); fprintf( files->incall, "\n#include \n" ); @@ -93,7 +90,6 @@ void print_file_header( FILES * files ) { files -> initall = FILEcreate( "schema.cc" ); fprintf( files->initall, "\n// in the exp2cxx source code, this file is generally referred to as files->initall or schemainit\n" ); fprintf( files->initall, "#include \"schema.h\"\n" ); - fprintf( files->initall, "#include \"sc_memmgr.h\"\n" ); fprintf( files->initall, "class Registry;\n" ); fprintf( files->initall, "\nvoid SchemaInit (Registry & reg) {\n" ); @@ -107,7 +103,6 @@ void print_file_header( FILES * files ) { files -> create = FILEcreate( "SdaiAll.cc" ); fprintf( files->create, "\n// in the exp2cxx source code, this file is generally referred to as files->create or createall\n" ); fprintf( files->create, "#include \"schema.h\"\n" ); - fprintf( files->create, "#include \"sc_memmgr.h\"\n" ); fprintf( files->create, "\nvoid InitSchemasAndEnts (Registry & reg) {\n" ); // This file declares all entity classes as incomplete types. This will @@ -387,7 +382,8 @@ void INITFileFinish( FILE * initfile, Schema schema ) { ** Status: ******************************************************************/ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix ) { - char schnm[MAX_LEN], sufnm[MAX_LEN], fnm[MAX_LEN], *np; + int ocnt = 0; + char schnm[MAX_LEN+1], sufnm[MAX_LEN+1], fnm[MAX_LEN+1], *np; /* sufnm = schema name + suffix */ FILE * libfile, * incfile, @@ -404,11 +400,20 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix ) /* 1. header file */ sprintf( schnm, "%s%s", SCHEMA_FILE_PREFIX, StrToUpper( SCHEMAget_name( schema ) ) ); //TODO change file names to CamelCase? if( suffix == 0 ) { - sprintf( sufnm, "%s", schnm ); + ocnt = snprintf( sufnm, MAX_LEN, "%s", schnm ); + if( ocnt > MAX_LEN ) { + std::cerr << "Warning - " << __FILE__ << " line " << __LINE__ << " - sufnm not large enough to hold schnm\n"; + } } else { - sprintf( sufnm, "%s_%d", schnm, suffix ); + ocnt = snprintf( sufnm, MAX_LEN, "%s_%d", schnm, suffix ); + if( ocnt > MAX_LEN ) { + std::cerr << "Warning - " << __FILE__ << " line " << __LINE__ << " - sufnm not large enough to hold string\n"; + } + } + ocnt = snprintf( fnm, MAX_LEN, "%s.h", sufnm ); + if( ocnt > MAX_LEN ) { + std::cerr << "Warning - " << __FILE__ << " line " << __LINE__ << " - sufnm not large enough to hold string\n"; } - sprintf( fnm, "%s.h", sufnm ); if( !( incfile = ( files -> inc ) = FILEcreate( fnm ) ) ) { return; @@ -416,7 +421,6 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix ) fprintf( files->inc, "\n// in the exp2cxx source code, this file is generally referred to as files->inc or incfile\n" ); fprintf( incfile, "#include \"schema.h\"\n" ); - fprintf( incfile, "#include \"sc_memmgr.h\"\n" ); np = fnm + strlen( fnm ) - 1; /* point to end of constant part of string */ @@ -437,7 +441,6 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix ) #else fprintf( libfile, "#include \"schema.h\"\n" ); #endif - fprintf( libfile, "#include \"sc_memmgr.h\"\n" ); fprintf( libfile, "\n#ifdef SC_LOGGING \n" @@ -449,7 +452,11 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix ) fprintf( libfile, "\n#include \"%s.h\"\n", schnm ); // 3. header for namespace to contain all formerly-global variables - sprintf( fnm, "%sNames.h", schnm ); + ocnt = snprintf( fnm, MAX_LEN, "%sNames.h", schnm ); + if( ocnt > MAX_LEN ) { + std::cerr << "Warning - " << __FILE__ << " line " << __LINE__ << " - fnm not large enough to hold schnm\n"; + } + if( !( files->names = FILEcreate( fnm ) ) ) { return; } @@ -464,7 +471,11 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix ) if( suffix <= 1 ) { /* I.e., if this is our first pass with schema */ - sprintf( fnm, "%s.init.cc", schnm ); + ocnt = snprintf( fnm, MAX_LEN, "%s.init.cc", schnm ); + if( ocnt > MAX_LEN ) { + std::cerr << "Warning - " << __FILE__ << " line " << __LINE__ << " - fnm not large enough to hold string\n"; + } + /* Note - We use schnm (without the "_x" suffix sufnm has) since we ** only generate a single init.cc file. */ if( !( initfile = ( files -> init ) = FILEcreate( fnm ) ) ) { @@ -483,8 +494,7 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix ) "#include \"schema.h\"\n" "#endif\n" ); #endif - fprintf( initfile, "#include \n#include \n" ); - fprintf( initfile, "#include \n" ); + fprintf( initfile, "#include \"clstepcore/Registry.h\"\n#include \n" ); fprintf( initfile, "\nvoid %sInit (Registry& reg) {\n", schnm ); @@ -527,7 +537,11 @@ void SCHEMAprint( Schema schema, FILES * files, void * complexCol, int suffix ) fprintf( files->classes, "\n#include \"%sNames.h\"\n", schnm ); } else { /* Just reopen the .init.cc (in append mode): */ - sprintf( fnm, "%s.init.cc", schnm ); + ocnt = snprintf( fnm, MAX_LEN, "%s.init.cc", schnm ); + if( ocnt > MAX_LEN ) { + std::cerr << "Warning - " << __FILE__ << " line " << __LINE__ << " - sufnm not large enough to hold string\n"; + } + initfile = files->init = fopen( fnm, "a" ); } @@ -608,7 +622,7 @@ void getMCPrint( Express express, FILE * schema_h, FILE * schema_cc ) { ** Status: 24-Feb-1992 new -kcm ******************************************************************/ void EXPRESSPrint( Express express, ComplexCollect & col, FILES * files ) { - char fnm [MAX_LEN], *np; + char fnm [MAX_LEN+1], *np; const char * schnm; /* schnm is really "express name" */ FILE * libfile; FILE * incfile; @@ -629,7 +643,7 @@ void EXPRESSPrint( Express express, ComplexCollect & col, FILES * files ) { } fprintf( files->inc, "\n// in the exp2cxx source code, this file is generally referred to as files->inc or incfile\n" ); - fprintf( incfile, "#include \n" ); + fprintf( incfile, "#include \"core/sdai.h\" \n" ); np = fnm + strlen( fnm ) - 1; /* point to end of constant part of string */ /* 1.9 init unity files (large translation units, faster compilation) */ @@ -724,7 +738,7 @@ void print_file( Express express ) { print_file_header( &files ); if( separate_schemas ) { - print_schemas_separate( express, ( void * )&col, &files ); + print_schemas_separate( express, &col, &files ); } else { print_schemas_combined( express, col, &files ); } diff --git a/src/exp2cxx/collect.cc b/src/exp2cxx/collect.cc index 2d3c352f3..a50b808be 100644 --- a/src/exp2cxx/collect.cc +++ b/src/exp2cxx/collect.cc @@ -1,7 +1,7 @@ /***************************************************************************** * collect.cc * * * - * Description: ComplexCollect is the container structure for all ofthe com- * + * Description: ComplexCollect is the container structure for all of the com-* * plex entity information in a schema. It contains a list of * * ComplexList structures each of which corresponds to one set * * of subtype/supertype information about the schema. This file * @@ -12,7 +12,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include void ComplexCollect::insert( ComplexList * c ) /* @@ -89,8 +88,8 @@ ComplexList * ComplexCollect::find( char * name ) int ComplexCollect::supports( EntNode * ents ) /* * Determines if the parent schema supports the instantiation of a complex - * type consisting of the the entities named in ents. Does so by attempt- - * ing to match ents against the ComplexLists in clists. If one of the + * type consisting of the entities named in ents. Does so by attempting + * to match ents against the ComplexLists in clists. If one of the * nodes of ents has multSupers set to TRUE (it has >1 supertype), it * should be included in >1 CList. A more complicated algorithm is applied * to match it, as described in the commenting. diff --git a/src/exp2cxx/complexSupport.h b/src/exp2cxx/complexSupport.h index 8277a03fa..f285c506d 100644 --- a/src/exp2cxx/complexSupport.h +++ b/src/exp2cxx/complexSupport.h @@ -73,7 +73,7 @@ class EntNode { public: EntNode( const char * nm = "" ) : next( 0 ), mark( NOMARK ), multSupers( 0 ) { - strcpy( name, nm ); + strncpy( name, nm, BUFSIZ ); } EntNode( char *[] ); // given a list, create a linked list of EntNodes ~EntNode() { @@ -116,7 +116,7 @@ class EntNode { private: MarkType mark; - char name[BUFSIZ]; + char name[BUFSIZ+1]; int multSupers; // do I correspond to an entity with >1 supertype? }; @@ -225,7 +225,7 @@ class SimpleList : public EntList { void write( ostream & ); private: - char name[BUFSIZ]; // Name of entity we correspond to. + char name[BUFSIZ+1]; // Name of entity we correspond to. MarkType I_marked; // Did I mark, and with what type of mark. }; diff --git a/src/exp2cxx/complexlist.cc b/src/exp2cxx/complexlist.cc index 84acd5a20..485f0609d 100644 --- a/src/exp2cxx/complexlist.cc +++ b/src/exp2cxx/complexlist.cc @@ -11,7 +11,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include ComplexList::~ComplexList() /* @@ -151,7 +150,7 @@ int ComplexList::contains( EntNode * ents ) ours = ours->next; } if( ours == NULL || *ours > *theirs ) { - // If either of these occured, we couldn't find one of ours which + // If either of these occurred, we couldn't find one of ours which // matched the current "theirs". return FALSE; } diff --git a/src/exp2cxx/entlist.cc b/src/exp2cxx/entlist.cc index e27114294..bd45be671 100644 --- a/src/exp2cxx/entlist.cc +++ b/src/exp2cxx/entlist.cc @@ -14,7 +14,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include int EntList::siblings() /* diff --git a/src/exp2cxx/entnode.cc b/src/exp2cxx/entnode.cc index 50f3a8659..569dcde87 100644 --- a/src/exp2cxx/entnode.cc +++ b/src/exp2cxx/entnode.cc @@ -12,7 +12,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include EntNode::EntNode( char * namelist[] ) /* diff --git a/src/exp2cxx/expressbuild.cc b/src/exp2cxx/expressbuild.cc index a1c665656..d55465eef 100644 --- a/src/exp2cxx/expressbuild.cc +++ b/src/exp2cxx/expressbuild.cc @@ -12,7 +12,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include // Local function prototypes: static void initEnts( Express ); @@ -286,7 +285,7 @@ void ComplexList::addImplicitSubs( Linked_List subs, ComplexCollect * col ) AndOrList * ao = 0; LISTdo( subs, subEnt, Entity ) - strcpy( node.name, ENTITYget_name( subEnt ) ); + strncpy( node.name, ENTITYget_name( subEnt ), BUFSIZ ); if( !contains( &node ) ) { // We've found an implicit subtype. #ifdef COMPLEX_INFO diff --git a/src/exp2cxx/fedex_main.c b/src/exp2cxx/fedex_main.c index 9803db703..b83976daf 100644 --- a/src/exp2cxx/fedex_main.c +++ b/src/exp2cxx/fedex_main.c @@ -72,17 +72,17 @@ * Added * to typedefs. Replaced warning kludges with ERRORoption. */ -#include #include #include #include "../express/express.h" #include "../express/resolve.h" -#include +#include "./trace_fprintf.h" extern void print_fedex_version( void ); static void exp2cxx_usage( void ) { + char *warnings_help_msg = ERRORget_warnings_help("\t", "\n"); fprintf( stderr, "usage: %s [-s|-S] [-a|-A] [-L] [-v] [-d # | -d 9 -l nnn -u nnn] [-n] [-p ] {-w|-i } express_file\n", EXPRESSprogram_name ); fprintf( stderr, "where\t-s or -S uses only single inheritance in the generated C++ classes\n" ); fprintf( stderr, "\t-a or -A generates the early bound access functions for entity classes the old way (without an underscore)\n" ); @@ -95,9 +95,7 @@ static void exp2cxx_usage( void ) { fprintf( stderr, "\t-i warning ignore\n" ); fprintf( stderr, "and is one of:\n" ); fprintf( stderr, "\tnone\n\tall\n" ); - LISTdo( ERRORwarnings, opt, Error_Warning ) - fprintf( stderr, "\t%s\n", opt->name ); - LISTod + fprintf( stderr, "%s", warnings_help_msg); fprintf( stderr, "and is one or more of:\n" ); fprintf( stderr, " e entity\n" ); fprintf( stderr, " p procedure\n" ); diff --git a/src/exp2cxx/genCxxFilenames.c b/src/exp2cxx/genCxxFilenames.c index f6e87d11a..14bee4295 100644 --- a/src/exp2cxx/genCxxFilenames.c +++ b/src/exp2cxx/genCxxFilenames.c @@ -1,10 +1,6 @@ #include "genCxxFilenames.h" #include "class_strings.h" -#if defined( _WIN32 ) || defined ( __WIN32__ ) -# define snprintf _snprintf -#endif - /** \file genCxxFilenames.c * functions shared by exp2cxx and the schema scanner. * The latter creates, at configuration time, a list @@ -16,8 +12,8 @@ */ /* these buffers are shared amongst (and potentially overwritten by) all functions in this file */ -char impl[ BUFSIZ ] = {0}; -char header[ BUFSIZ ] = {0}; +char impl[ BUFSIZ+1 ] = {0}; +char header[ BUFSIZ+1 ] = {0}; /* struct containing pointers to above buffers. pointers are 'const char *' */ filenames_t fnames = { impl, header }; diff --git a/src/exp2cxx/match-ors.cc b/src/exp2cxx/match-ors.cc index 1b86622e4..41d5af88c 100644 --- a/src/exp2cxx/match-ors.cc +++ b/src/exp2cxx/match-ors.cc @@ -14,7 +14,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include MatchType AndOrList::matchORs( EntNode * ents ) /* diff --git a/src/exp2cxx/multlist.cc b/src/exp2cxx/multlist.cc index a92a86874..5d2cade84 100644 --- a/src/exp2cxx/multlist.cc +++ b/src/exp2cxx/multlist.cc @@ -13,7 +13,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include MultList::~MultList() /* @@ -336,7 +335,7 @@ int JoinList::acceptChoice( EntNode * ents ) if( child->viable >= MATCHSOME ) { // Only mark children which have new nodes they can mark. (This // condition is important. Sometimes, there will be children who - // can mark but whose vaiable val = SATISFIED. This will be the + // can mark but whose variable val = SATISFIED. This will be the // case if there's another EntList with higher priority which can // also mark this node. (For example, if an AND has an OR and a // SIMPLE child, the SIMPLE wins so that we'll have fewer OR diff --git a/src/exp2cxx/multpass.c b/src/exp2cxx/multpass.c index 10294b35a..03e1eb885 100644 --- a/src/exp2cxx/multpass.c +++ b/src/exp2cxx/multpass.c @@ -31,11 +31,10 @@ * Date: 04/09/97 * *****************************************************************************/ -#include #include #include "classes.h" -#include +#include "./trace_fprintf.h" int isAggregateType( const Type t ); @@ -56,7 +55,7 @@ static void addUseRefNames( Schema, FILE * ); /** * Generates the C++ files corresponding to a list of schemas. Does so in * multiple passes through the schemas. In each pass it checks for enti- - * ties which are subtypes of entites in other schemas which have not yet + * ties which are subtypes of entities in other schemas which have not yet * been processed. Such entities cannot be processed in that pass until * their supertypes have been defined. It also checks for entities which * have enum or select attributes which have not been processed, and for @@ -160,7 +159,7 @@ void print_schemas_separate( Express express, void * complexCol, FILES * files ) // which hasn't been closed yet. (That's done on 2nd line below.)) */ fprintf( files->initall, " reg.SetCompCollect( gencomplex() );\n" ); fprintf( files->initall, "}\n\n" ); - fprintf( files->incall, "\n#include \n" ); + fprintf( files->incall, "\n#include \"clstepcore/complexSupport.h\"\n" ); fprintf( files->incall, "ComplexCollect *gencomplex();\n" ); /* Function GetModelContents() is printed at the end of the schema.xx @@ -189,7 +188,7 @@ static void initializeMarks( Express express ) DICTdo_type_init( express->symbol_table, &de_sch, OBJ_SCHEMA ); while( ( schema = ( Scope )DICTdo( &de_sch ) ) != 0 ) { schema->search_id = UNPROCESSED; - schema->clientData = ( int * )sc_malloc( sizeof( int ) ); + schema->clientData = ( int * )malloc( sizeof( int ) ); *( int * )schema->clientData = 0; SCOPEdo_entities( schema, ent, de_ent ) ent->search_id = NOTKNOWN; @@ -207,7 +206,7 @@ static void cleanupMarks( Express express ) { DICTdo_type_init( express->symbol_table, &de_sch, OBJ_SCHEMA ); while( ( schema = ( Scope )DICTdo( &de_sch ) ) != 0 ) { if( schema->clientData ) { - sc_free( schema->clientData ); + free( schema->clientData ); schema->clientData = NULL; } } @@ -608,7 +607,7 @@ static int inSchema( Scope scope, Scope super ) static void addRenameTypedefs( Schema schema, FILE * classes ) { DictionaryEntry de; Type i; - char nm[BUFSIZ], basenm[BUFSIZ]; + char nm[BUFSIZ+1], basenm[BUFSIZ+1]; static bool firsttime = true; SCOPEdo_types( schema, t, de ) { @@ -654,7 +653,7 @@ static void addAggrTypedefs( Schema schema, FILE * classes ) { DictionaryEntry de; Type i; static bool firsttime = true; - char nm[BUFSIZ]; + char nm[BUFSIZ+1]; SCOPEdo_types( schema, t, de ) { if( TYPEis_aggregate( t ) ) { @@ -691,7 +690,7 @@ static void addUseRefNames( Schema schema, FILE * create ) { Dictionary useRefDict; DictionaryEntry de; Rename * rnm; - char * oldnm, schNm[BUFSIZ]; + char * oldnm, schNm[BUFSIZ+1]; static bool firsttime = true; if( ( useRefDict = schema->u.schema->usedict ) != NULL ) { diff --git a/src/exp2cxx/non-ors.cc b/src/exp2cxx/non-ors.cc index 2ef5dd803..6b05bb378 100644 --- a/src/exp2cxx/non-ors.cc +++ b/src/exp2cxx/non-ors.cc @@ -11,7 +11,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include MatchType SimpleList::matchNonORs( EntNode * ents ) /* diff --git a/src/exp2cxx/orlist.cc b/src/exp2cxx/orlist.cc index dd0c9db88..809804320 100644 --- a/src/exp2cxx/orlist.cc +++ b/src/exp2cxx/orlist.cc @@ -11,7 +11,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include int OrList::hit( const char * nm ) /* diff --git a/src/exp2cxx/print.cc b/src/exp2cxx/print.cc index 0b1398a6d..b338c5954 100644 --- a/src/exp2cxx/print.cc +++ b/src/exp2cxx/print.cc @@ -8,7 +8,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include // Local function prototypes: static char * joinText( JoinType, char * ); diff --git a/src/exp2cxx/selects.c b/src/exp2cxx/selects.c index 23b89cbc5..5d975cdde 100644 --- a/src/exp2cxx/selects.c +++ b/src/exp2cxx/selects.c @@ -16,13 +16,12 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7. extern int multiple_inheritance; -#include #include #include "classes.h" #include "classes_type.h" #include "classes_attribute.h" -#include +#include "./trace_fprintf.h" #define BASE_SELECT "SDAI_Select" @@ -34,7 +33,7 @@ extern int multiple_inheritance; ((t)->u.type->body->type == integer_) || \ ((t)->u.type->body->type == number_) ) #define PRINT_BUG_REPORT \ - fprintf( f, " std::cerr << __FILE__ << \":\" << __LINE__ << \": ERROR" \ + fprintf( f, "std::cerr << __FILE__ << \":\" << __LINE__ << \": ERROR" \ " in schema library: \\n\" \n << _POC_ << \"\\n\\n\";\n"); #define PRINT_SELECTBUG_WARNING(f) \ @@ -67,7 +66,7 @@ const char * TYPEget_utype( Type t ) { /** determines if the given entity is a member of the list. RETURNS the member if it is a member; otherwise 0 is returned. */ -Generic LISTmember( const Linked_List list, Generic e ) { +void *LISTmember( const Linked_List list, void *e ) { Link node; for( node = list->mark->next; node != list->mark; node = node->next ) if( e == node -> data ) { @@ -123,7 +122,7 @@ static int compareOrigTypes( Type a, Type b ) { compareOrigTypes() above). */ const char * utype_member( const Linked_List list, const Type check, int rename ) { - static char r [BUFSIZ]; + static char r [BUFSIZ+1]; bool checkIsEntity = TYPEis_entity( check ); LISTdo( list, t, Type ) { @@ -156,7 +155,7 @@ Linked_List SELgetnew_dmlist( const Type type ) { /* if t\'s underlying type is not already in newlist, */ if( ! utype_member( newlist, t, 0 ) ) { - LISTadd_last( newlist, ( Generic ) t ); + LISTadd_last( newlist, t ); } LISTod; @@ -244,7 +243,7 @@ int unique_types( const Linked_List list ) { RETURNS 1 if true, else 0. */ int duplicate_utype_member( const Linked_List list, const Type check ) { - char b [BUFSIZ]; + char b [BUFSIZ+1]; if( TYPEis_entity( check ) ) { return FALSE; @@ -304,9 +303,9 @@ int find_duplicate_list( const Type type, Linked_List * duplicate_list ) { if( !utype_member( *duplicate_list, u, 1 ) ) { /** if not already a duplicate **/ if( utype_member( temp, u, 1 ) ) { - LISTadd_first( *duplicate_list, ( Generic ) u ); + LISTadd_first( *duplicate_list, u ); } else { - LISTadd_first( temp, ( Generic ) u ); + LISTadd_first( temp, u ); } } LISTod; @@ -376,7 +375,7 @@ void non_unique_types_vector( const Type type, int * tvec ) { tvec[tnumber]++; break; default: - fprintf( stderr, "non_unique_types_vector: can't handle unknow type %d\n", + fprintf( stderr, "non_unique_types_vector: can't handle unknown type %d\n", TYPEget_body( t )->type ); abort(); } @@ -397,7 +396,7 @@ char * non_unique_types_string( const Type type ) { non_unique_types_vector( type, tvec ); /* build type string from vector */ - typestr = ( char * )sc_malloc( BUFSIZ ); + typestr = ( char * )malloc( BUFSIZ + 1 ); typestr[0] = '\0'; strcat( typestr, ( char * )"(" ); for( i = 0; i <= tnumber; i++ ) { @@ -450,8 +449,8 @@ char * non_unique_types_string( const Type type ) { * \returns the attribute 'check' if an attribute with the same name is on the list, 0 otherwise */ Variable ATTR_LISTmember( Linked_List l, Variable check ) { - char nm [BUFSIZ]; - char cur [BUFSIZ]; + char nm [BUFSIZ+1]; + char cur [BUFSIZ+1]; generate_attribute_name( check, nm ); LISTdo( l, a, Variable ) { @@ -480,7 +479,7 @@ Linked_List SEL_TYPEgetnew_attribute_list( const Type type ) { attrs = ENTITYget_all_attributes( cur ); LISTdo_n( attrs, a, Variable, b ) { if( ! ATTR_LISTmember( newlist, a ) ) { - LISTadd_first( newlist, ( Generic ) a ); + LISTadd_first( newlist, a ); } } LISTod } @@ -494,9 +493,9 @@ Linked_List SEL_TYPEgetnew_attribute_list( const Type type ) { void TYPEselect_inc_print_vars( const Type type, FILE * f, Linked_List dups ) { int size, j; Linked_List data_members = SELgetnew_dmlist( type ); - char dmname [BUFSIZ], - classnm [BUFSIZ], - tdnm [BUFSIZ]; + char dmname [BUFSIZ+1], + classnm [BUFSIZ+1], + tdnm [BUFSIZ+1]; strncpy( classnm, SelectName( TYPEget_name( type ) ), BUFSIZ ); classnm[BUFSIZ-1] = '\0'; @@ -583,8 +582,8 @@ void TYPEselect_inc_print_vars( const Type type, FILE * f, Linked_List dups ) { * class. */ void TYPEselect_inc_print( const Type type, FILE * f ) { - char n[BUFSIZ]; /* class name */ - char tdnm [BUFSIZ]; /* TypeDescriptor name */ + char n[BUFSIZ+1]; /* class name */ + char tdnm [BUFSIZ+1]; /* TypeDescriptor name */ Linked_List dups; int dup_result; Linked_List attrs; @@ -708,8 +707,8 @@ void TYPEselect_inc_print( const Type type, FILE * f ) { void TYPEselect_lib_print_part_one( const Type type, FILE * f, Linked_List dups, char * n ) { #define schema_name SCHEMAget_name(schema) - char tdnm[BUFSIZ], - nm[BUFSIZ]; + char tdnm[BUFSIZ+1], + nm[BUFSIZ+1]; int size = strlen( n ) * 2 + 4, j; /* size - for formatting output */ strncpy( tdnm, TYPEtd_name( type ), BUFSIZ ); @@ -741,7 +740,11 @@ void TYPEselect_lib_print_part_one( const Type type, FILE * f, if( ( TYPEis_entity( t ) ) || ( !utype_member( dups, t, 1 ) ) ) { if( isAggregateType( t ) && ( t->u.type->body->base ) ) { fprintf( f, " _%s = new %s;\n", SEL_ITEMget_dmname( t ), TYPEget_utype( t ) ); - } + } else if (TYPEis_entity(t)) { + // Per TYPEget_utype, any TYPEis_entity is an + // SDAI_Application_instance_ptr - initialize it here. + fprintf(f, " _%s = NULL;\n", SEL_ITEMget_dmname(t)); + } } } LISTod fprintf( f, " nullify();\n" ); @@ -889,8 +892,8 @@ Linked_List ENTITYget_expanded_entities( Entity e, Linked_List l ) { Linked_List supers; Entity super; - if( ! LISTmember( l, ( Generic ) e ) ) { - LISTadd_first( l, ( Generic ) e ); + if( ! LISTmember( l, e ) ) { + LISTadd_first( l, e ); } if( multiple_inheritance ) { @@ -939,7 +942,7 @@ static int memberOfEntPrimary( Entity ent, Variable uattr ) { int result; ENTITYget_first_attribs( ent, attrlist ); - result = ( LISTmember( attrlist, ( Generic ) uattr ) != 0 ); + result = ( LISTmember( attrlist, uattr ) != 0 ); LIST_destroy( attrlist ); return result; } @@ -983,7 +986,7 @@ void TYPEselect_lib_part_three_getter( const Type type, const char * classnm, co /* if the underlying type is that item's type, call the underlying_item's * member function if it is the same attribute */ if( VARis_overrider( ENT_TYPEget_entity( t ), uattr ) ) { - /* update attribute_func_name because is has been overriden */ + /* update attribute_func_name because is has been overridden */ generate_attribute_func_name( uattr, funcnm ); } else { generate_attribute_func_name( a, funcnm ); @@ -1049,10 +1052,10 @@ void TYPEselect_lib_part_three_getter( const Type type, const char * classnm, co void TYPEselect_lib_print_part_three( const Type type, FILE * f, char * classnm ) { #define ENTITYget_type(e) ((e)->u.entity->type) - char uent[BUFSIZ], /* name of underlying entity type */ - utype[BUFSIZ], /* underlying type name */ - attrnm [BUFSIZ], /* attribute name -> data member = _attrnm */ - funcnm[BUFSIZ]; /* access function name = Attrnm */ + char uent[BUFSIZ+1], /* name of underlying entity type */ + utype[BUFSIZ+1], /* underlying type name */ + attrnm [BUFSIZ+1], /* attribute name -> data member = _attrnm */ + funcnm[BUFSIZ+1]; /* access function name = Attrnm */ Linked_List items = SEL_TYPEget_items( type ); /* all the items in the select type */ Linked_List attrs = SEL_TYPEgetnew_attribute_list( type ); @@ -1151,7 +1154,7 @@ void TYPEselect_lib_print_part_three( const Type type, FILE * f, char * classnm * TYPEselect_lib_print_part_four prints part 4 of the SDAI document of a select class. */ void TYPEselect_lib_print_part_four( const Type type, FILE * f, Linked_List dups, char * n ) { - char x[BUFSIZ]; + char x[BUFSIZ+1]; fprintf( f, "\n // part 4\n" ); @@ -1280,7 +1283,7 @@ void TYPEselect_init_print( const Type type, FILE * f ) { } void TYPEselect_lib_part21( const Type type, FILE * f ) { - char n[BUFSIZ]; /* pointers to class name(s) */ + char n[BUFSIZ+1]; /* pointers to class name(s) */ const char * dm; /* data member name */ Linked_List data_members = SELgetnew_dmlist( type ); @@ -1493,7 +1496,7 @@ void TYPEselect_lib_part21( const Type type, FILE * f ) { " _%s = ReadEntityRef(in, &_error, \",)\", instances, addFileId);\n", dm ); fprintf( f, " if( _%s && ( _%s != S_ENTITY_NULL) &&\n " - " ( CurrentUnderlyingType()->CanBe( _%s->getEDesc() ) ) ) {\n" + " ( CurrentUnderlyingType()->CanBe( _%s->eDesc ) ) ) {\n" " return severity();\n", dm, dm, dm ); fprintf( f, " } else {\n " @@ -1554,7 +1557,7 @@ void TYPEselect_lib_part21( const Type type, FILE * f ) { void TYPEselect_lib_StrToVal( const Type type, FILE * f ) { - char n[BUFSIZ]; /* pointers to class name */ + char n[BUFSIZ+1]; /* pointers to class name */ Linked_List data_members = SELgetnew_dmlist( type ); int enum_cnt = 0; @@ -1680,7 +1683,7 @@ void SELlib_print_protected( const Type type, FILE * f ) { if( TYPEis_select( t ) ) { fprintf( f, " // %s\n" /* item name */ - " if( %s->CanBe( se->getEDesc() ) ) {\n" + " if( %s->CanBe( se->eDesc ) ) {\n" " _%s.AssignEntity (se);\n" /* underlying data member */ " return SetUnderlyingType (%s);\n" /* td */ " }\n", @@ -1713,7 +1716,7 @@ void SELlib_print_protected( const Type type, FILE * f ) { * TYPEselect_lib_print prints the member functions (definitions) of a select class. */ void TYPEselect_lib_print( const Type type, FILE * f ) { - char n[BUFSIZ], m[BUFSIZ]; + char n[BUFSIZ+1], m[BUFSIZ+1]; const char * z; /* pointers to class name(s) */ Linked_List dups; int dup_result; @@ -1850,7 +1853,7 @@ void TYPEselect_lib_print( const Type type, FILE * f ) { void TYPEselect_print( Type t, FILES * files, Schema schema ) { SelectTag tag, tmp; Type i, bt; /* type of elements in an aggregate */ - char nm[BUFSIZ], tdnm[BUFSIZ]; + char nm[BUFSIZ+1], tdnm[BUFSIZ+1]; FILE * inc = files->inc; /* if type is already marked, return */ @@ -1862,7 +1865,7 @@ void TYPEselect_print( Type t, FILES * files, Schema schema ) { } /* mark the type as being processed */ - tag = ( SelectTag ) sc_malloc( sizeof( struct SelectTag_ ) ); + tag = ( SelectTag ) malloc( sizeof( struct SelectTag_ ) ); tag -> started = 1; tag -> complete = 0; TYPEput_clientData( t, ( ClientData ) tag ); @@ -1934,11 +1937,11 @@ void TYPEselect_print( Type t, FILES * files, Schema schema ) { DAR - moved to TYPEprint_init() - to keep init info together. */ tag -> complete = 1; - sc_free( tag ); + free( tag ); } #undef BASE_SELECT /************************************************************************** -******** END of SELECT TYPE +******** END of SELECT TYPE **************************************************************************/ diff --git a/src/exp2cxx/test/inverse_qualifiers.cmake b/src/exp2cxx/test/inverse_qualifiers.cmake index dec2fe81f..ed26e0b75 100644 --- a/src/exp2cxx/test/inverse_qualifiers.cmake +++ b/src/exp2cxx/test/inverse_qualifiers.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 2.8 ) +cmake_minimum_required( VERSION 3.12 ) # executable is ${EXE}, input file is ${INFILE} diff --git a/src/exp2cxx/test/unique_qualifiers.cmake b/src/exp2cxx/test/unique_qualifiers.cmake index b4b41f5df..13225bd6a 100644 --- a/src/exp2cxx/test/unique_qualifiers.cmake +++ b/src/exp2cxx/test/unique_qualifiers.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 2.8 ) +cmake_minimum_required( VERSION 3.12 ) # executable is ${EXE}, input file is ${INFILE} diff --git a/src/base/sc_trace_fprintf.c b/src/exp2cxx/trace_fprintf.c similarity index 92% rename from src/base/sc_trace_fprintf.c rename to src/exp2cxx/trace_fprintf.c index 95ca6b9c6..3a3838d67 100644 --- a/src/base/sc_trace_fprintf.c +++ b/src/exp2cxx/trace_fprintf.c @@ -1,8 +1,7 @@ - #include #include -#include "sc_trace_fprintf.h" +#include "trace_fprintf.h" void trace_fprintf( char const * sourcefile, int line, FILE * file, const char * format, ... ) { va_list args; diff --git a/src/base/sc_trace_fprintf.h b/src/exp2cxx/trace_fprintf.h similarity index 85% rename from src/base/sc_trace_fprintf.h rename to src/exp2cxx/trace_fprintf.h index b7aa05fa2..9e5c2f073 100644 --- a/src/base/sc_trace_fprintf.h +++ b/src/exp2cxx/trace_fprintf.h @@ -1,7 +1,7 @@ #ifndef SC_TRACE_FPRINTF_H #define SC_TRACE_FPRINTF_H -/** \file sc_trace_fprintf.h +/** \file trace_fprintf.h * Used to track the source file and line where generated code is printed from * When enabled, comments are printed into the generated files for every 'fprintf': * / * source: scl/src/exp2cxx/selects.c:1375 * / @@ -20,7 +20,7 @@ extern "C" { /** Used to find where generated c++ originates from in exp2cxx. * To enable, configure with 'cmake .. -DSC_TRACE_FPRINTF=ON' */ - SC_BASE_EXPORT void trace_fprintf( char const * sourcefile, int line, FILE * file, const char * format, ... ); + void trace_fprintf( char const * sourcefile, int line, FILE * file, const char * format, ... ); #ifdef __cplusplus } #endif diff --git a/src/exp2cxx/trynext.cc b/src/exp2cxx/trynext.cc index 97cacc8a3..e2c0a0edf 100644 --- a/src/exp2cxx/trynext.cc +++ b/src/exp2cxx/trynext.cc @@ -12,7 +12,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include // Local function prototypes: static EntList * firstCandidate( EntList * ); diff --git a/src/exp2cxx/write.cc b/src/exp2cxx/write.cc index 39f32367c..da1ecb747 100644 --- a/src/exp2cxx/write.cc +++ b/src/exp2cxx/write.cc @@ -11,7 +11,6 @@ *****************************************************************************/ #include "complexSupport.h" -#include // Local function prototypes: static void writeheader( ostream &, int ); @@ -117,7 +116,7 @@ static void writeheader( ostream & os, int noLists ) << " * file, however, there are no complex entities, so this\n" << " * function is a stub.\n" << " */" << endl << endl; - os << "#include \"complexSupport.h\"\n#include \"sc_memmgr.h\"\n\n"; + os << "#include \"clstepcore/complexSupport.h\"\n\n"; os << "ComplexCollect *gencomplex()" << endl; os << "{" << endl; return; @@ -129,10 +128,10 @@ static void writeheader( ostream & os, int noLists ) << " * support structures. The structures will be used in the SCL to\n" << " * validate user requests to instantiate complex entities.\n" << " */" << endl << endl; - os << "#include \"complexSupport.h\"\n#include \"sc_memmgr.h\"\n\n"; + os << "#include \"clstepcore/complexSupport.h\"\n\n"; os << "ComplexCollect *gencomplex()" << endl; os << " /*" << endl - << " * This function contains instantiation statments for all the\n" + << " * This function contains instantiation statements for all the\n" << " * ComplexLists and EntLists in a ComplexCollect. The instan-\n" << " * stiation statements were generated in order of lower to\n" << " * higher, and last to first to simplify creating some of the\n" diff --git a/src/exp2python/CMakeLists.txt b/src/exp2python/CMakeLists.txt index ae4ac9686..60ced2d77 100644 --- a/src/exp2python/CMakeLists.txt +++ b/src/exp2python/CMakeLists.txt @@ -3,7 +3,6 @@ if(SC_PYTHON_GENERATOR) include_directories( ${SC_SOURCE_DIR}/include ${SC_SOURCE_DIR}/include/express - ${SC_SOURCE_DIR}/src/base ) add_definitions(-DHAVE_CONFIG_H) @@ -29,11 +28,8 @@ if(SC_PYTHON_GENERATOR) ../exp2cxx/write.cc ../exp2cxx/print.cc ) - SC_ADDEXEC(exp2python "${exp2python_SOURCES}" "express;base") + SC_ADDEXEC(exp2python SOURCES ${exp2python_SOURCES} LINK_LIBRARIES express) - if(NOT SC_IS_SUBBUILD AND SC_GIT_VERSION) - add_dependencies(exp2python version_string) - endif(NOT SC_IS_SUBBUILD AND SC_GIT_VERSION) endif(SC_PYTHON_GENERATOR) # Local Variables: diff --git a/src/exp2python/DESIGN.txt b/src/exp2python/DESIGN.txt index 7d70c6635..0481bef18 100644 --- a/src/exp2python/DESIGN.txt +++ b/src/exp2python/DESIGN.txt @@ -60,7 +60,7 @@ class AP203Parser(SCL.Part21.Parser): def __init__(self, ...): SCL.Part21.Parser.__init__(self) - # schema entities would be passed to the underlying lexer to faciliate exact rule matches + # schema entities would be passed to the underlying lexer to facilitate exact rule matches self.lexer.register_entities(self.entities) # validating form diff --git a/src/exp2python/examples/unitary_schemas/gcc_incomplete_type.py b/src/exp2python/examples/unitary_schemas/gcc_incomplete_type.py deleted file mode 100644 index 75448145b..000000000 --- a/src/exp2python/examples/unitary_schemas/gcc_incomplete_type.py +++ /dev/null @@ -1,28 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'gcc_incomplete_type' - -schema_scope = sys.modules[__name__] - -# Defined datatype maths_number -class maths_number(NUMBER): - def __init__(self,*kargs): - pass - -# SELECT TYPE atom_based_value -atom_based_value = SELECT( - 'maths_number', - 'atom_based_tuple', - scope = schema_scope) -atom_based_tuple = LIST(0,None,'atom_based_value', scope = schema_scope) diff --git a/src/exp2python/examples/unitary_schemas/generate_schemas_modules.py b/src/exp2python/examples/unitary_schemas/generate_schemas_modules.py deleted file mode 100644 index bc61a1a01..000000000 --- a/src/exp2python/examples/unitary_schemas/generate_schemas_modules.py +++ /dev/null @@ -1,13 +0,0 @@ -__doc__= ''' This script runs exp2python over each EXPRESS schema in the test/unitary_schemas folder''' - -unitary_schemas_path = '../../../../test/unitary_schemas' -exp2python_path = '../../../../cmake-build/bin/exp2python' - -import subprocess -import glob -import os - -unitary_schemas = glob.glob(os.path.join(unitary_schemas_path,'*.exp')) - -for unitary_schema in unitary_schemas: - subprocess.call([exp2python_path,unitary_schema]) \ No newline at end of file diff --git a/src/exp2python/examples/unitary_schemas/index_attribute.py b/src/exp2python/examples/unitary_schemas/index_attribute.py deleted file mode 100644 index 4824586a3..000000000 --- a/src/exp2python/examples/unitary_schemas/index_attribute.py +++ /dev/null @@ -1,140 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'index_attribute' - -schema_scope = sys.modules[__name__] - -common_datum_list = LIST(1,None,'datum_reference_element', scope = schema_scope) -# Defined datatype label -class label(STRING): - def __init__(self,*kargs): - pass - -# SELECT TYPE datum_or_common_datum -datum_or_common_datum = SELECT( - 'common_datum_list', - 'datum', - scope = schema_scope) - -#################### - # ENTITY shape_aspect # -#################### -class shape_aspect(BaseEntityClass): - '''Entity shape_aspect definition. - - :param name - :type name:label - - :param of_shape - :type of_shape:product_definition_shape - ''' - def __init__( self , name,of_shape, ): - self.name = name - self.of_shape = of_shape - - @apply - def name(): - def fget( self ): - return self._name - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument name is mantatory and can not be set to None') - if not check_type(value,label): - self._name = label(value) - else: - self._name = value - return property(**locals()) - - @apply - def of_shape(): - def fget( self ): - return self._of_shape - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument of_shape is mantatory and can not be set to None') - if not check_type(value,product_definition_shape): - self._of_shape = product_definition_shape(value) - else: - self._of_shape = value - return property(**locals()) - def wr1(self): - eval_wr1_wr = (SIZEOF(USEDIN(self,'INDEX_ATTRIBUTE.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1) - if not eval_wr1_wr: - raise AssertionError('Rule wr1 violated') - else: - return eval_wr1_wr - - -#################### - # ENTITY general_datum_reference # -#################### -class general_datum_reference(shape_aspect): - '''Entity general_datum_reference definition. - - :param base - :type base:datum_or_common_datum - ''' - def __init__( self , inherited0__name , inherited1__of_shape , base, ): - shape_aspect.__init__(self , inherited0__name , inherited1__of_shape , ) - self.base = base - - @apply - def base(): - def fget( self ): - return self._base - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument base is mantatory and can not be set to None') - if not check_type(value,datum_or_common_datum): - self._base = datum_or_common_datum(value) - else: - self._base = value - return property(**locals()) - def wr1(self): - eval_wr1_wr = (( not ('INDEX_ATTRIBUTE.COMMON_DATUM_LIST' == TYPEOF(self.base))) or (self.self.shape_aspect.self.of_shape == self.base[1].self.shape_aspect.self.of_shape)) - if not eval_wr1_wr: - raise AssertionError('Rule wr1 violated') - else: - return eval_wr1_wr - - -#################### - # ENTITY product_definition_shape # -#################### -class product_definition_shape(BaseEntityClass): - '''Entity product_definition_shape definition. - ''' - # This class does not define any attribute. - pass - -#################### - # ENTITY datum_reference_element # -#################### -class datum_reference_element(general_datum_reference): - '''Entity datum_reference_element definition. - ''' - def __init__( self , inherited0__name , inherited1__of_shape , inherited2__base , ): - general_datum_reference.__init__(self , inherited0__name , inherited1__of_shape , inherited2__base , ) - -#################### - # ENTITY datum # -#################### -class datum(shape_aspect): - '''Entity datum definition. - ''' - def __init__( self , inherited0__name , inherited1__of_shape , ): - shape_aspect.__init__(self , inherited0__name , inherited1__of_shape , ) diff --git a/src/exp2python/examples/unitary_schemas/multiple_rep.py b/src/exp2python/examples/unitary_schemas/multiple_rep.py deleted file mode 100644 index 6dfcc4a0b..000000000 --- a/src/exp2python/examples/unitary_schemas/multiple_rep.py +++ /dev/null @@ -1,353 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'multiple_rep' - -schema_scope = sys.modules[__name__] - -# Defined datatype text -class text(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype representation_context -class representation_context(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype identifier -class identifier(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype shape_definition -class shape_definition(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype transformation -class transformation(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype representation_item -class representation_item(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype characterized_product_definition -class characterized_product_definition(STRING): - def __init__(self,*kargs): - pass - -# SELECT TYPE characterized_definition -characterized_definition = SELECT( - 'characterized_object', - 'characterized_product_definition', - 'shape_definition', - scope = schema_scope) -# Defined datatype label -class label(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype characterized_object -class characterized_object(STRING): - def __init__(self,*kargs): - pass - - -#################### - # ENTITY representation_relationship # -#################### -class representation_relationship(BaseEntityClass): - '''Entity representation_relationship definition. - - :param name - :type name:label - - :param rep_1 - :type rep_1:representation - - :param rep_2 - :type rep_2:representation - ''' - def __init__( self , name,rep_1,rep_2, ): - self.name = name - self.rep_1 = rep_1 - self.rep_2 = rep_2 - - @apply - def name(): - def fget( self ): - return self._name - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument name is mantatory and can not be set to None') - if not check_type(value,label): - self._name = label(value) - else: - self._name = value - return property(**locals()) - - @apply - def rep_1(): - def fget( self ): - return self._rep_1 - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument rep_1 is mantatory and can not be set to None') - if not check_type(value,representation): - self._rep_1 = representation(value) - else: - self._rep_1 = value - return property(**locals()) - - @apply - def rep_2(): - def fget( self ): - return self._rep_2 - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument rep_2 is mantatory and can not be set to None') - if not check_type(value,representation): - self._rep_2 = representation(value) - else: - self._rep_2 = value - return property(**locals()) - -#################### - # ENTITY shape_representation_relationship # -#################### -class shape_representation_relationship(representation_relationship): - '''Entity shape_representation_relationship definition. - ''' - def __init__( self , inherited0__name , inherited1__rep_1 , inherited2__rep_2 , ): - representation_relationship.__init__(self , inherited0__name , inherited1__rep_1 , inherited2__rep_2 , ) - def wr1(self): - eval_wr1_wr = ('MULTIPLE_REP.SHAPE_REPRESENTATION' == (TYPEOF(self.self.representation_relationship.self.rep_1) + TYPEOF(self.self.representation_relationship.self.rep_2))) - if not eval_wr1_wr: - raise AssertionError('Rule wr1 violated') - else: - return eval_wr1_wr - - -#################### - # ENTITY representation # -#################### -class representation(BaseEntityClass): - '''Entity representation definition. - - :param name - :type name:label - - :param items - :type items:SET(1,None,'STRING', scope = schema_scope) - - :param context_of_items - :type context_of_items:representation_context - ''' - def __init__( self , name,items,context_of_items, ): - self.name = name - self.items = items - self.context_of_items = context_of_items - - @apply - def name(): - def fget( self ): - return self._name - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument name is mantatory and can not be set to None') - if not check_type(value,label): - self._name = label(value) - else: - self._name = value - return property(**locals()) - - @apply - def items(): - def fget( self ): - return self._items - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument items is mantatory and can not be set to None') - if not check_type(value,SET(1,None,'STRING', scope = schema_scope)): - self._items = SET(value) - else: - self._items = value - return property(**locals()) - - @apply - def context_of_items(): - def fget( self ): - return self._context_of_items - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument context_of_items is mantatory and can not be set to None') - if not check_type(value,representation_context): - self._context_of_items = representation_context(value) - else: - self._context_of_items = value - return property(**locals()) - def wr1(self): - eval_wr1_wr = (SIZEOF(USEDIN(self,'MULTIPLE_REP.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1) - if not eval_wr1_wr: - raise AssertionError('Rule wr1 violated') - else: - return eval_wr1_wr - - def wr2(self): - eval_wr2_wr = (SIZEOF(USEDIN(self,'MULTIPLE_REP.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1) - if not eval_wr2_wr: - raise AssertionError('Rule wr2 violated') - else: - return eval_wr2_wr - - -#################### - # ENTITY property_definition # -#################### -class property_definition(BaseEntityClass): - '''Entity property_definition definition. - - :param name - :type name:label - - :param definition - :type definition:characterized_definition - ''' - def __init__( self , name,definition, ): - self.name = name - self.definition = definition - - @apply - def name(): - def fget( self ): - return self._name - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument name is mantatory and can not be set to None') - if not check_type(value,label): - self._name = label(value) - else: - self._name = value - return property(**locals()) - - @apply - def definition(): - def fget( self ): - return self._definition - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument definition is mantatory and can not be set to None') - if not check_type(value,characterized_definition): - self._definition = characterized_definition(value) - else: - self._definition = value - return property(**locals()) - def wr1(self): - eval_wr1_wr = (SIZEOF(USEDIN(self,'MULTIPLE_REP.' + 'ID_ATTRIBUTE.IDENTIFIED_ITEM')) <= 1) - if not eval_wr1_wr: - raise AssertionError('Rule wr1 violated') - else: - return eval_wr1_wr - - -#################### - # ENTITY context_dependent_shape_representation # -#################### -class context_dependent_shape_representation(BaseEntityClass): - '''Entity context_dependent_shape_representation definition. - - :param representation_relation - :type representation_relation:shape_representation_relationship - ''' - def __init__( self , representation_relation, ): - self.representation_relation = representation_relation - - @apply - def representation_relation(): - def fget( self ): - return self._representation_relation - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument representation_relation is mantatory and can not be set to None') - if not check_type(value,shape_representation_relationship): - self._representation_relation = shape_representation_relationship(value) - else: - self._representation_relation = value - return property(**locals()) - def wr2(self): - eval_wr2_wr = (SIZEOF(USEDIN(self,'MULTIPLE_REP.' + 'DESCRIPTION_ATTRIBUTE.DESCRIBED_ITEM')) <= 1) - if not eval_wr2_wr: - raise AssertionError('Rule wr2 violated') - else: - return eval_wr2_wr - - def wr3(self): - eval_wr3_wr = (SIZEOF(USEDIN(self,'MULTIPLE_REP.' + 'NAME_ATTRIBUTE.NAMED_ITEM')) <= 1) - if not eval_wr3_wr: - raise AssertionError('Rule wr3 violated') - else: - return eval_wr3_wr - - -#################### - # ENTITY definitional_representation_relationship # -#################### -class definitional_representation_relationship(representation_relationship): - '''Entity definitional_representation_relationship definition. - ''' - def __init__( self , inherited0__name , inherited1__rep_1 , inherited2__rep_2 , ): - representation_relationship.__init__(self , inherited0__name , inherited1__rep_1 , inherited2__rep_2 , ) - -#################### - # ENTITY component_2d_location # -#################### -class component_2d_location(context_dependent_shape_representation,shape_representation_relationship,definitional_representation_relationship): - '''Entity component_2d_location definition. - - :param context_dependent_shape_representation_representation_relation - :type context_dependent_shape_representation_representation_relation:component_2d_location - ''' - def __init__( self , inherited0__representation_relation , inherited1__name , inherited2__rep_1 , inherited3__rep_2 , inherited4__name , inherited5__rep_1 , inherited6__rep_2 , ): - context_dependent_shape_representation.__init__(self , inherited0__representation_relation , ) - shape_representation_relationship.__init__(self , inherited1__name , inherited2__rep_1 , inherited3__rep_2 , ) - definitional_representation_relationship.__init__(self , inherited4__name , inherited5__rep_1 , inherited6__rep_2 , ) - - @apply - def context_dependent_shape_representation_representation_relation(): - def fget( self ): - attribute_eval = self - return attribute_eval - def fset( self, value ): - # DERIVED argument - raise AssertionError('Argument context_dependent_shape_representation_representation_relation is DERIVED. It is computed and can not be set to any value') - return property(**locals()) - def wr1(self): - eval_wr1_wr = (self.self.representation_relationship.self.name == 'component 2d location') - if not eval_wr1_wr: - raise AssertionError('Rule wr1 violated') - else: - return eval_wr1_wr - diff --git a/src/exp2python/examples/unitary_schemas/test_array.py b/src/exp2python/examples/unitary_schemas/test_array.py deleted file mode 100644 index d7f77e69e..000000000 --- a/src/exp2python/examples/unitary_schemas/test_array.py +++ /dev/null @@ -1,43 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_array' - -schema_scope = sys.modules[__name__] - - -#################### - # ENTITY point # -#################### -class point(BaseEntityClass): - '''Entity point definition. - - :param coords - :type coords:ARRAY(1,3,'REAL', scope = schema_scope) - ''' - def __init__( self , coords, ): - self.coords = coords - - @apply - def coords(): - def fget( self ): - return self._coords - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument coords is mantatory and can not be set to None') - if not check_type(value,ARRAY(1,3,'REAL', scope = schema_scope)): - self._coords = ARRAY(value) - else: - self._coords = value - return property(**locals()) diff --git a/src/exp2python/examples/unitary_schemas/test_array_of_array_of_simple_types.py b/src/exp2python/examples/unitary_schemas/test_array_of_array_of_simple_types.py deleted file mode 100644 index 32e8c5456..000000000 --- a/src/exp2python/examples/unitary_schemas/test_array_of_array_of_simple_types.py +++ /dev/null @@ -1,43 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_array_of_array_of_simple_types' - -schema_scope = sys.modules[__name__] - - -#################### - # ENTITY transformation # -#################### -class transformation(BaseEntityClass): - '''Entity transformation definition. - - :param rotation - :type rotation:ARRAY(1,3,ARRAY(1,3,'REAL', scope = schema_scope)) - ''' - def __init__( self , rotation, ): - self.rotation = rotation - - @apply - def rotation(): - def fget( self ): - return self._rotation - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument rotation is mantatory and can not be set to None') - if not check_type(value,ARRAY(1,3,ARRAY(1,3,'REAL', scope = schema_scope))): - self._rotation = ARRAY(value) - else: - self._rotation = value - return property(**locals()) diff --git a/src/exp2python/examples/unitary_schemas/test_array_of_simple_types.py b/src/exp2python/examples/unitary_schemas/test_array_of_simple_types.py deleted file mode 100644 index 09a6ca5e5..000000000 --- a/src/exp2python/examples/unitary_schemas/test_array_of_simple_types.py +++ /dev/null @@ -1,79 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_array_of_simple_types' - -schema_scope = sys.modules[__name__] - - -#################### - # ENTITY point # -#################### -class point(BaseEntityClass): - '''Entity point definition. - - :param arr_real - :type arr_real:ARRAY(1,3,'REAL', scope = schema_scope) - - :param arr_string - :type arr_string:ARRAY(1,3,'STRING', scope = schema_scope) - - :param arr_integer - :type arr_integer:ARRAY(1,None,'INTEGER', scope = schema_scope) - ''' - def __init__( self , arr_real,arr_string,arr_integer, ): - self.arr_real = arr_real - self.arr_string = arr_string - self.arr_integer = arr_integer - - @apply - def arr_real(): - def fget( self ): - return self._arr_real - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument arr_real is mantatory and can not be set to None') - if not check_type(value,ARRAY(1,3,'REAL', scope = schema_scope)): - self._arr_real = ARRAY(value) - else: - self._arr_real = value - return property(**locals()) - - @apply - def arr_string(): - def fget( self ): - return self._arr_string - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument arr_string is mantatory and can not be set to None') - if not check_type(value,ARRAY(1,3,'STRING', scope = schema_scope)): - self._arr_string = ARRAY(value) - else: - self._arr_string = value - return property(**locals()) - - @apply - def arr_integer(): - def fget( self ): - return self._arr_integer - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument arr_integer is mantatory and can not be set to None') - if not check_type(value,ARRAY(1,None,'INTEGER', scope = schema_scope)): - self._arr_integer = ARRAY(value) - else: - self._arr_integer = value - return property(**locals()) diff --git a/src/exp2python/examples/unitary_schemas/test_derived_attribute.py b/src/exp2python/examples/unitary_schemas/test_derived_attribute.py deleted file mode 100644 index 61da680f6..000000000 --- a/src/exp2python/examples/unitary_schemas/test_derived_attribute.py +++ /dev/null @@ -1,123 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_derived_attribute' - -schema_scope = sys.modules[__name__] - - -#################### - # ENTITY vector # -#################### -class vector(BaseEntityClass): - '''Entity vector definition. - ''' - # This class does not define any attribute. - pass - -#################### - # ENTITY circle # -#################### -class circle(BaseEntityClass): - '''Entity circle definition. - - :param centre - :type centre:point - - :param radius - :type radius:REAL - - :param axis - :type axis:vector - - :param area - :type area:REAL - - :param perimeter - :type perimeter:REAL - ''' - def __init__( self , centre,radius,axis, ): - self.centre = centre - self.radius = radius - self.axis = axis - - @apply - def centre(): - def fget( self ): - return self._centre - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument centre is mantatory and can not be set to None') - if not check_type(value,point): - self._centre = point(value) - else: - self._centre = value - return property(**locals()) - - @apply - def radius(): - def fget( self ): - return self._radius - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument radius is mantatory and can not be set to None') - if not check_type(value,REAL): - self._radius = REAL(value) - else: - self._radius = value - return property(**locals()) - - @apply - def axis(): - def fget( self ): - return self._axis - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument axis is mantatory and can not be set to None') - if not check_type(value,vector): - self._axis = vector(value) - else: - self._axis = value - return property(**locals()) - - @apply - def area(): - def fget( self ): - attribute_eval = ( PI * (self.radius ** 2)) - return attribute_eval - def fset( self, value ): - # DERIVED argument - raise AssertionError('Argument area is DERIVED. It is computed and can not be set to any value') - return property(**locals()) - - @apply - def perimeter(): - def fget( self ): - attribute_eval = ((2 * PI ) * self.radius) - return attribute_eval - def fset( self, value ): - # DERIVED argument - raise AssertionError('Argument perimeter is DERIVED. It is computed and can not be set to any value') - return property(**locals()) - -#################### - # ENTITY point # -#################### -class point(BaseEntityClass): - '''Entity point definition. - ''' - # This class does not define any attribute. - pass diff --git a/src/exp2python/examples/unitary_schemas/test_entity_where_rule.py b/src/exp2python/examples/unitary_schemas/test_entity_where_rule.py deleted file mode 100644 index 89f305645..000000000 --- a/src/exp2python/examples/unitary_schemas/test_entity_where_rule.py +++ /dev/null @@ -1,322 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_entity_where_rule' - -schema_scope = sys.modules[__name__] - -# Defined datatype label -class label(STRING): - def __init__(self,*kargs): - pass - - -#################### - # ENTITY unit_vector # -#################### -class unit_vector(BaseEntityClass): - '''Entity unit_vector definition. - - :param a - :type a:REAL - - :param b - :type b:REAL - - :param c - :type c:REAL - ''' - def __init__( self , a,b,c, ): - self.a = a - self.b = b - self.c = c - - @apply - def a(): - def fget( self ): - return self._a - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument a is mantatory and can not be set to None') - if not check_type(value,REAL): - self._a = REAL(value) - else: - self._a = value - return property(**locals()) - - @apply - def b(): - def fget( self ): - return self._b - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument b is mantatory and can not be set to None') - if not check_type(value,REAL): - self._b = REAL(value) - else: - self._b = value - return property(**locals()) - - @apply - def c(): - def fget( self ): - return self._c - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument c is mantatory and can not be set to None') - if not check_type(value,REAL): - self._c = REAL(value) - else: - self._c = value - return property(**locals()) - def length_1(self): - eval_length_1_wr = ((((self.a ** 2) + (self.b ** 2)) + (self.c ** 2)) == 1) - if not eval_length_1_wr: - raise AssertionError('Rule length_1 violated') - else: - return eval_length_1_wr - - -#################### - # ENTITY address # -#################### -class address(BaseEntityClass): - '''Entity address definition. - - :param internal_location - :type internal_location:label - - :param street_number - :type street_number:label - - :param street - :type street:label - - :param postal_box - :type postal_box:label - - :param town - :type town:label - - :param region - :type region:label - - :param postal_code - :type postal_code:label - - :param country - :type country:label - - :param facsimile_number - :type facsimile_number:label - - :param telephone_number - :type telephone_number:label - - :param electronic_mail_address - :type electronic_mail_address:label - - :param telex_number - :type telex_number:label - ''' - def __init__( self , internal_location,street_number,street,postal_box,town,region,postal_code,country,facsimile_number,telephone_number,electronic_mail_address,telex_number, ): - self.internal_location = internal_location - self.street_number = street_number - self.street = street - self.postal_box = postal_box - self.town = town - self.region = region - self.postal_code = postal_code - self.country = country - self.facsimile_number = facsimile_number - self.telephone_number = telephone_number - self.electronic_mail_address = electronic_mail_address - self.telex_number = telex_number - - @apply - def internal_location(): - def fget( self ): - return self._internal_location - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._internal_location = label(value) - else: - self._internal_location = value - else: - self._internal_location = value - return property(**locals()) - - @apply - def street_number(): - def fget( self ): - return self._street_number - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._street_number = label(value) - else: - self._street_number = value - else: - self._street_number = value - return property(**locals()) - - @apply - def street(): - def fget( self ): - return self._street - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._street = label(value) - else: - self._street = value - else: - self._street = value - return property(**locals()) - - @apply - def postal_box(): - def fget( self ): - return self._postal_box - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._postal_box = label(value) - else: - self._postal_box = value - else: - self._postal_box = value - return property(**locals()) - - @apply - def town(): - def fget( self ): - return self._town - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._town = label(value) - else: - self._town = value - else: - self._town = value - return property(**locals()) - - @apply - def region(): - def fget( self ): - return self._region - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._region = label(value) - else: - self._region = value - else: - self._region = value - return property(**locals()) - - @apply - def postal_code(): - def fget( self ): - return self._postal_code - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._postal_code = label(value) - else: - self._postal_code = value - else: - self._postal_code = value - return property(**locals()) - - @apply - def country(): - def fget( self ): - return self._country - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._country = label(value) - else: - self._country = value - else: - self._country = value - return property(**locals()) - - @apply - def facsimile_number(): - def fget( self ): - return self._facsimile_number - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._facsimile_number = label(value) - else: - self._facsimile_number = value - else: - self._facsimile_number = value - return property(**locals()) - - @apply - def telephone_number(): - def fget( self ): - return self._telephone_number - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._telephone_number = label(value) - else: - self._telephone_number = value - else: - self._telephone_number = value - return property(**locals()) - - @apply - def electronic_mail_address(): - def fget( self ): - return self._electronic_mail_address - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._electronic_mail_address = label(value) - else: - self._electronic_mail_address = value - else: - self._electronic_mail_address = value - return property(**locals()) - - @apply - def telex_number(): - def fget( self ): - return self._telex_number - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._telex_number = label(value) - else: - self._telex_number = value - else: - self._telex_number = value - return property(**locals()) - def wr1(self): - eval_wr1_wr = (((((((((((EXISTS(self.internal_location) or EXISTS(self.street_number)) or EXISTS(self.street)) or EXISTS(self.postal_box)) or EXISTS(self.town)) or EXISTS(self.region)) or EXISTS(self.postal_code)) or EXISTS(self.country)) or EXISTS(self.facsimile_number)) or EXISTS(self.telephone_number)) or EXISTS(self.electronic_mail_address)) or EXISTS(self.telex_number)) - if not eval_wr1_wr: - raise AssertionError('Rule wr1 violated') - else: - return eval_wr1_wr - diff --git a/src/exp2python/examples/unitary_schemas/test_enum_entity_name.py b/src/exp2python/examples/unitary_schemas/test_enum_entity_name.py deleted file mode 100644 index 5285ef88b..000000000 --- a/src/exp2python/examples/unitary_schemas/test_enum_entity_name.py +++ /dev/null @@ -1,32 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_enum_entity_name' - -schema_scope = sys.modules[__name__] - - -# ENUMERATION TYPE simple_datum_reference_modifier -simple_datum_reference_modifier = ENUMERATION( - 'line', - 'translation', - scope = schema_scope) - -#################### - # ENTITY line # -#################### -class line(BaseEntityClass): - '''Entity line definition. - ''' - # This class does not define any attribute. - pass diff --git a/src/exp2python/examples/unitary_schemas/test_enums_same_name.py b/src/exp2python/examples/unitary_schemas/test_enums_same_name.py deleted file mode 100644 index 4a446be99..000000000 --- a/src/exp2python/examples/unitary_schemas/test_enums_same_name.py +++ /dev/null @@ -1,29 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_enums_same_name' - -schema_scope = sys.modules[__name__] - - -# ENUMERATION TYPE hair_color -hair_color = ENUMERATION( - 'bald', - 'red', - scope = schema_scope) - -# ENUMERATION TYPE favorite_color -favorite_color = ENUMERATION( - 'clear', - 'red', - scope = schema_scope) diff --git a/src/exp2python/examples/unitary_schemas/test_function.py b/src/exp2python/examples/unitary_schemas/test_function.py deleted file mode 100644 index 72a90c1e4..000000000 --- a/src/exp2python/examples/unitary_schemas/test_function.py +++ /dev/null @@ -1,80 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_function' - -schema_scope = sys.modules[__name__] - - -#################### - # ENTITY dummy # -#################### -class dummy(BaseEntityClass): - '''Entity dummy definition. - ''' - # This class does not define any attribute. - pass - -#################### - # FUNCTION add # -#################### -def add(r1,r2,): - ''' - :param r1 - :type r1:REAL - :param r2 - :type r2:REAL - ''' - result = r1 + r2 - return result - -#################### - # FUNCTION pow_n # -#################### -def pow_n(r1,n,): - ''' - :param r1 - :type r1:REAL - :param n - :type n:INTEGER - ''' - if (n == 0): - return 1 - else: - result = r1 - for i in range(1,n,1): - result = result * r1 - return result - -#################### - # FUNCTION case_1 # -#################### -def case_1(a,): - ''' - :param a - :type a:INTEGER - ''' - case_selector = a - if case_selector == 1: - x = SIN(a) - elif case_selector == 2: - x = EXP(a) - elif case_selector == 3: - x = SQRT(a) - elif case_selector == 4: - x = LOG(a) - elif case_selector == 5: - x = LOG(a) - else: - x = 0 - return x diff --git a/src/exp2python/examples/unitary_schemas/test_multiple_inheritance.py b/src/exp2python/examples/unitary_schemas/test_multiple_inheritance.py deleted file mode 100644 index 1598e2e7f..000000000 --- a/src/exp2python/examples/unitary_schemas/test_multiple_inheritance.py +++ /dev/null @@ -1,582 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_multiple_inheritance' - -schema_scope = sys.modules[__name__] - -# SELECT TYPE classification_item -classification_item = SELECT( - 'person_and_organization_address', - 'address', - scope = schema_scope) -# Defined datatype text -class text(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype identifier -class identifier(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype label -class label(STRING): - def __init__(self,*kargs): - pass - - -#################### - # ENTITY address # -#################### -class address(BaseEntityClass): - '''Entity address definition. - - :param internal_location - :type internal_location:label - - :param street_number - :type street_number:label - - :param street - :type street:label - - :param postal_box - :type postal_box:label - - :param town - :type town:label - - :param region - :type region:label - - :param postal_code - :type postal_code:label - - :param country - :type country:label - - :param facsimile_number - :type facsimile_number:label - - :param telephone_number - :type telephone_number:label - - :param electronic_mail_address - :type electronic_mail_address:label - - :param telex_number - :type telex_number:label - ''' - def __init__( self , internal_location,street_number,street,postal_box,town,region,postal_code,country,facsimile_number,telephone_number,electronic_mail_address,telex_number, ): - self.internal_location = internal_location - self.street_number = street_number - self.street = street - self.postal_box = postal_box - self.town = town - self.region = region - self.postal_code = postal_code - self.country = country - self.facsimile_number = facsimile_number - self.telephone_number = telephone_number - self.electronic_mail_address = electronic_mail_address - self.telex_number = telex_number - - @apply - def internal_location(): - def fget( self ): - return self._internal_location - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._internal_location = label(value) - else: - self._internal_location = value - else: - self._internal_location = value - return property(**locals()) - - @apply - def street_number(): - def fget( self ): - return self._street_number - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._street_number = label(value) - else: - self._street_number = value - else: - self._street_number = value - return property(**locals()) - - @apply - def street(): - def fget( self ): - return self._street - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._street = label(value) - else: - self._street = value - else: - self._street = value - return property(**locals()) - - @apply - def postal_box(): - def fget( self ): - return self._postal_box - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._postal_box = label(value) - else: - self._postal_box = value - else: - self._postal_box = value - return property(**locals()) - - @apply - def town(): - def fget( self ): - return self._town - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._town = label(value) - else: - self._town = value - else: - self._town = value - return property(**locals()) - - @apply - def region(): - def fget( self ): - return self._region - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._region = label(value) - else: - self._region = value - else: - self._region = value - return property(**locals()) - - @apply - def postal_code(): - def fget( self ): - return self._postal_code - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._postal_code = label(value) - else: - self._postal_code = value - else: - self._postal_code = value - return property(**locals()) - - @apply - def country(): - def fget( self ): - return self._country - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._country = label(value) - else: - self._country = value - else: - self._country = value - return property(**locals()) - - @apply - def facsimile_number(): - def fget( self ): - return self._facsimile_number - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._facsimile_number = label(value) - else: - self._facsimile_number = value - else: - self._facsimile_number = value - return property(**locals()) - - @apply - def telephone_number(): - def fget( self ): - return self._telephone_number - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._telephone_number = label(value) - else: - self._telephone_number = value - else: - self._telephone_number = value - return property(**locals()) - - @apply - def electronic_mail_address(): - def fget( self ): - return self._electronic_mail_address - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._electronic_mail_address = label(value) - else: - self._electronic_mail_address = value - else: - self._electronic_mail_address = value - return property(**locals()) - - @apply - def telex_number(): - def fget( self ): - return self._telex_number - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._telex_number = label(value) - else: - self._telex_number = value - else: - self._telex_number = value - return property(**locals()) - -#################### - # ENTITY personal_address # -#################### -class personal_address(address): - '''Entity personal_address definition. - - :param people - :type people:SET(1,None,'person', scope = schema_scope) - - :param description - :type description:text - ''' - def __init__( self , inherited0__internal_location , inherited1__street_number , inherited2__street , inherited3__postal_box , inherited4__town , inherited5__region , inherited6__postal_code , inherited7__country , inherited8__facsimile_number , inherited9__telephone_number , inherited10__electronic_mail_address , inherited11__telex_number , people,description, ): - address.__init__(self , inherited0__internal_location , inherited1__street_number , inherited2__street , inherited3__postal_box , inherited4__town , inherited5__region , inherited6__postal_code , inherited7__country , inherited8__facsimile_number , inherited9__telephone_number , inherited10__electronic_mail_address , inherited11__telex_number , ) - self.people = people - self.description = description - - @apply - def people(): - def fget( self ): - return self._people - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument people is mantatory and can not be set to None') - if not check_type(value,SET(1,None,'person', scope = schema_scope)): - self._people = SET(value) - else: - self._people = value - return property(**locals()) - - @apply - def description(): - def fget( self ): - return self._description - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,text): - self._description = text(value) - else: - self._description = value - else: - self._description = value - return property(**locals()) - -#################### - # ENTITY organizational_address # -#################### -class organizational_address(address): - '''Entity organizational_address definition. - - :param organizations - :type organizations:SET(1,None,'organization', scope = schema_scope) - - :param description - :type description:text - ''' - def __init__( self , inherited0__internal_location , inherited1__street_number , inherited2__street , inherited3__postal_box , inherited4__town , inherited5__region , inherited6__postal_code , inherited7__country , inherited8__facsimile_number , inherited9__telephone_number , inherited10__electronic_mail_address , inherited11__telex_number , organizations,description, ): - address.__init__(self , inherited0__internal_location , inherited1__street_number , inherited2__street , inherited3__postal_box , inherited4__town , inherited5__region , inherited6__postal_code , inherited7__country , inherited8__facsimile_number , inherited9__telephone_number , inherited10__electronic_mail_address , inherited11__telex_number , ) - self.organizations = organizations - self.description = description - - @apply - def organizations(): - def fget( self ): - return self._organizations - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument organizations is mantatory and can not be set to None') - if not check_type(value,SET(1,None,'organization', scope = schema_scope)): - self._organizations = SET(value) - else: - self._organizations = value - return property(**locals()) - - @apply - def description(): - def fget( self ): - return self._description - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,text): - self._description = text(value) - else: - self._description = value - else: - self._description = value - return property(**locals()) - -#################### - # ENTITY person # -#################### -class person(BaseEntityClass): - '''Entity person definition. - - :param id - :type id:identifier - - :param last_name - :type last_name:label - - :param first_name - :type first_name:label - - :param middle_names - :type middle_names:LIST(1,None,'STRING', scope = schema_scope) - - :param prefix_titles - :type prefix_titles:LIST(1,None,'STRING', scope = schema_scope) - - :param suffix_titles - :type suffix_titles:LIST(1,None,'STRING', scope = schema_scope) - ''' - def __init__( self , id,last_name,first_name,middle_names,prefix_titles,suffix_titles, ): - self.id = id - self.last_name = last_name - self.first_name = first_name - self.middle_names = middle_names - self.prefix_titles = prefix_titles - self.suffix_titles = suffix_titles - - @apply - def id(): - def fget( self ): - return self._id - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument id is mantatory and can not be set to None') - if not check_type(value,identifier): - self._id = identifier(value) - else: - self._id = value - return property(**locals()) - - @apply - def last_name(): - def fget( self ): - return self._last_name - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._last_name = label(value) - else: - self._last_name = value - else: - self._last_name = value - return property(**locals()) - - @apply - def first_name(): - def fget( self ): - return self._first_name - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,label): - self._first_name = label(value) - else: - self._first_name = value - else: - self._first_name = value - return property(**locals()) - - @apply - def middle_names(): - def fget( self ): - return self._middle_names - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,LIST(1,None,'STRING', scope = schema_scope)): - self._middle_names = LIST(value) - else: - self._middle_names = value - else: - self._middle_names = value - return property(**locals()) - - @apply - def prefix_titles(): - def fget( self ): - return self._prefix_titles - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,LIST(1,None,'STRING', scope = schema_scope)): - self._prefix_titles = LIST(value) - else: - self._prefix_titles = value - else: - self._prefix_titles = value - return property(**locals()) - - @apply - def suffix_titles(): - def fget( self ): - return self._suffix_titles - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,LIST(1,None,'STRING', scope = schema_scope)): - self._suffix_titles = LIST(value) - else: - self._suffix_titles = value - else: - self._suffix_titles = value - return property(**locals()) - def wr1(self): - eval_wr1_wr = (EXISTS(self.last_name) or EXISTS(self.first_name)) - if not eval_wr1_wr: - raise AssertionError('Rule wr1 violated') - else: - return eval_wr1_wr - - -#################### - # ENTITY organization # -#################### -class organization(BaseEntityClass): - '''Entity organization definition. - - :param id - :type id:identifier - - :param name - :type name:label - - :param description - :type description:text - ''' - def __init__( self , id,name,description, ): - self.id = id - self.name = name - self.description = description - - @apply - def id(): - def fget( self ): - return self._id - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,identifier): - self._id = identifier(value) - else: - self._id = value - else: - self._id = value - return property(**locals()) - - @apply - def name(): - def fget( self ): - return self._name - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument name is mantatory and can not be set to None') - if not check_type(value,label): - self._name = label(value) - else: - self._name = value - return property(**locals()) - - @apply - def description(): - def fget( self ): - return self._description - def fset( self, value ): - if value != None: # OPTIONAL attribute - if not check_type(value,text): - self._description = text(value) - else: - self._description = value - else: - self._description = value - return property(**locals()) - -#################### - # ENTITY person_and_organization_address # -#################### -class person_and_organization_address(organizational_address,personal_address): - '''Entity person_and_organization_address definition. - - :param organizational_address_organizations - :type organizational_address_organizations:SET(1,1,'organization', scope = schema_scope) - - :param personal_address_people - :type personal_address_people:SET(1,1,'person', scope = schema_scope) - ''' - def __init__( self , inherited0__internal_location , inherited1__street_number , inherited2__street , inherited3__postal_box , inherited4__town , inherited5__region , inherited6__postal_code , inherited7__country , inherited8__facsimile_number , inherited9__telephone_number , inherited10__electronic_mail_address , inherited11__telex_number , inherited12__organizations , inherited13__description , inherited14__internal_location , inherited15__street_number , inherited16__street , inherited17__postal_box , inherited18__town , inherited19__region , inherited20__postal_code , inherited21__country , inherited22__facsimile_number , inherited23__telephone_number , inherited24__electronic_mail_address , inherited25__telex_number , inherited26__people , inherited27__description , organizational_address_organizations,personal_address_people, ): - organizational_address.__init__(self , inherited0__internal_location , inherited1__street_number , inherited2__street , inherited3__postal_box , inherited4__town , inherited5__region , inherited6__postal_code , inherited7__country , inherited8__facsimile_number , inherited9__telephone_number , inherited10__electronic_mail_address , inherited11__telex_number , inherited12__organizations , inherited13__description , ) - personal_address.__init__(self , inherited14__internal_location , inherited15__street_number , inherited16__street , inherited17__postal_box , inherited18__town , inherited19__region , inherited20__postal_code , inherited21__country , inherited22__facsimile_number , inherited23__telephone_number , inherited24__electronic_mail_address , inherited25__telex_number , inherited26__people , inherited27__description , ) - self.organizational_address_organizations = organizational_address_organizations - self.personal_address_people = personal_address_people - - @apply - def organizational_address_organizations(): - def fget( self ): - return self._organizational_address_organizations - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument organizational_address_organizations is mantatory and can not be set to None') - if not check_type(value,SET(1,1,'organization', scope = schema_scope)): - self._organizational_address_organizations = SET(value) - else: - self._organizational_address_organizations = value - return property(**locals()) - - @apply - def personal_address_people(): - def fget( self ): - return self._personal_address_people - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument personal_address_people is mantatory and can not be set to None') - if not check_type(value,SET(1,1,'person', scope = schema_scope)): - self._personal_address_people = SET(value) - else: - self._personal_address_people = value - return property(**locals()) diff --git a/src/exp2python/examples/unitary_schemas/test_named_type.py b/src/exp2python/examples/unitary_schemas/test_named_type.py deleted file mode 100644 index beed4e578..000000000 --- a/src/exp2python/examples/unitary_schemas/test_named_type.py +++ /dev/null @@ -1,94 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_named_type' - -schema_scope = sys.modules[__name__] - -# Defined datatype measure -class measure(REAL): - def __init__(self,*kargs): - pass - -# Defined datatype type2 -class type2(INTEGER): - def __init__(self,*kargs): - pass - -# Defined datatype type3 -class type3(type2): - def __init__(self,*kargs): - pass - - -#################### - # ENTITY line # -#################### -class line(BaseEntityClass): - '''Entity line definition. - - :param line_length - :type line_length:measure - - :param other_param - :type other_param:type3 - - :param and_another - :type and_another:REAL - ''' - def __init__( self , line_length,other_param,and_another, ): - self.line_length = line_length - self.other_param = other_param - self.and_another = and_another - - @apply - def line_length(): - def fget( self ): - return self._line_length - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument line_length is mantatory and can not be set to None') - if not check_type(value,measure): - self._line_length = measure(value) - else: - self._line_length = value - return property(**locals()) - - @apply - def other_param(): - def fget( self ): - return self._other_param - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument other_param is mantatory and can not be set to None') - if not check_type(value,type3): - self._other_param = type3(value) - else: - self._other_param = value - return property(**locals()) - - @apply - def and_another(): - def fget( self ): - return self._and_another - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument and_another is mantatory and can not be set to None') - if not check_type(value,REAL): - self._and_another = REAL(value) - else: - self._and_another = value - return property(**locals()) diff --git a/src/exp2python/examples/unitary_schemas/test_select_data_type.py b/src/exp2python/examples/unitary_schemas/test_select_data_type.py deleted file mode 100644 index b30f5cd8b..000000000 --- a/src/exp2python/examples/unitary_schemas/test_select_data_type.py +++ /dev/null @@ -1,252 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_select_data_type' - -schema_scope = sys.modules[__name__] - -# SELECT TYPE permanent_attachment -permanent_attachment = SELECT( - 'glue', - 'weld', - scope = schema_scope) -# SELECT TYPE temporary_attachment -temporary_attachment = SELECT( - 'nail', - 'screw', - scope = schema_scope) -# SELECT TYPE attachment_method -attachment_method = SELECT( - 'permanent_attachment', - 'temporary_attachment', - scope = schema_scope) - -#################### - # ENTITY weld # -#################### -class weld(BaseEntityClass): - '''Entity weld definition. - - :param composition - :type composition:STRING - ''' - def __init__( self , composition, ): - self.composition = composition - - @apply - def composition(): - def fget( self ): - return self._composition - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument composition is mantatory and can not be set to None') - if not check_type(value,STRING): - self._composition = STRING(value) - else: - self._composition = value - return property(**locals()) - -#################### - # ENTITY glue # -#################### -class glue(BaseEntityClass): - '''Entity glue definition. - - :param composition - :type composition:STRING - - :param solvent - :type solvent:STRING - ''' - def __init__( self , composition,solvent, ): - self.composition = composition - self.solvent = solvent - - @apply - def composition(): - def fget( self ): - return self._composition - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument composition is mantatory and can not be set to None') - if not check_type(value,STRING): - self._composition = STRING(value) - else: - self._composition = value - return property(**locals()) - - @apply - def solvent(): - def fget( self ): - return self._solvent - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument solvent is mantatory and can not be set to None') - if not check_type(value,STRING): - self._solvent = STRING(value) - else: - self._solvent = value - return property(**locals()) - -#################### - # ENTITY wall_mounting # -#################### -class wall_mounting(BaseEntityClass): - '''Entity wall_mounting definition. - - :param mounting - :type mounting:STRING - - :param on - :type on:STRING - - :param using - :type using:attachment_method - ''' - def __init__( self , mounting,on,using, ): - self.mounting = mounting - self.on = on - self.using = using - - @apply - def mounting(): - def fget( self ): - return self._mounting - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument mounting is mantatory and can not be set to None') - if not check_type(value,STRING): - self._mounting = STRING(value) - else: - self._mounting = value - return property(**locals()) - - @apply - def on(): - def fget( self ): - return self._on - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument on is mantatory and can not be set to None') - if not check_type(value,STRING): - self._on = STRING(value) - else: - self._on = value - return property(**locals()) - - @apply - def using(): - def fget( self ): - return self._using - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument using is mantatory and can not be set to None') - if not check_type(value,attachment_method): - self._using = attachment_method(value) - else: - self._using = value - return property(**locals()) - -#################### - # ENTITY screw # -#################### -class screw(BaseEntityClass): - '''Entity screw definition. - - :param body_length - :type body_length:REAL - - :param pitch - :type pitch:REAL - ''' - def __init__( self , body_length,pitch, ): - self.body_length = body_length - self.pitch = pitch - - @apply - def body_length(): - def fget( self ): - return self._body_length - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument body_length is mantatory and can not be set to None') - if not check_type(value,REAL): - self._body_length = REAL(value) - else: - self._body_length = value - return property(**locals()) - - @apply - def pitch(): - def fget( self ): - return self._pitch - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument pitch is mantatory and can not be set to None') - if not check_type(value,REAL): - self._pitch = REAL(value) - else: - self._pitch = value - return property(**locals()) - -#################### - # ENTITY nail # -#################### -class nail(BaseEntityClass): - '''Entity nail definition. - - :param body_length - :type body_length:REAL - - :param head_area - :type head_area:REAL - ''' - def __init__( self , body_length,head_area, ): - self.body_length = body_length - self.head_area = head_area - - @apply - def body_length(): - def fget( self ): - return self._body_length - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument body_length is mantatory and can not be set to None') - if not check_type(value,REAL): - self._body_length = REAL(value) - else: - self._body_length = value - return property(**locals()) - - @apply - def head_area(): - def fget( self ): - return self._head_area - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument head_area is mantatory and can not be set to None') - if not check_type(value,REAL): - self._head_area = REAL(value) - else: - self._head_area = value - return property(**locals()) diff --git a/src/exp2python/examples/unitary_schemas/test_single_inheritance.py b/src/exp2python/examples/unitary_schemas/test_single_inheritance.py deleted file mode 100644 index e317b26df..000000000 --- a/src/exp2python/examples/unitary_schemas/test_single_inheritance.py +++ /dev/null @@ -1,121 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_single_inheritance' - -schema_scope = sys.modules[__name__] - -# Defined datatype length_measure -class length_measure(REAL): - def __init__(self,*kargs): - pass - -# Defined datatype label -class label(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype point -class point(REAL): - def __init__(self,*kargs): - pass - - -#################### - # ENTITY shape # -#################### -class shape(BaseEntityClass): - '''Entity shape definition. - - :param item_name - :type item_name:label - - :param number_of_sides - :type number_of_sides:INTEGER - ''' - def __init__( self , item_name,number_of_sides, ): - self.item_name = item_name - self.number_of_sides = number_of_sides - - @apply - def item_name(): - def fget( self ): - return self._item_name - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument item_name is mantatory and can not be set to None') - if not check_type(value,label): - self._item_name = label(value) - else: - self._item_name = value - return property(**locals()) - - @apply - def number_of_sides(): - def fget( self ): - return self._number_of_sides - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument number_of_sides is mantatory and can not be set to None') - if not check_type(value,INTEGER): - self._number_of_sides = INTEGER(value) - else: - self._number_of_sides = value - return property(**locals()) - -#################### - # ENTITY rectangle # -#################### -class rectangle(shape): - '''Entity rectangle definition. - - :param height - :type height:length_measure - - :param width - :type width:length_measure - ''' - def __init__( self , inherited0__item_name , inherited1__number_of_sides , height,width, ): - shape.__init__(self , inherited0__item_name , inherited1__number_of_sides , ) - self.height = height - self.width = width - - @apply - def height(): - def fget( self ): - return self._height - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument height is mantatory and can not be set to None') - if not check_type(value,length_measure): - self._height = length_measure(value) - else: - self._height = value - return property(**locals()) - - @apply - def width(): - def fget( self ): - return self._width - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument width is mantatory and can not be set to None') - if not check_type(value,length_measure): - self._width = length_measure(value) - else: - self._width = value - return property(**locals()) diff --git a/src/exp2python/examples/unitary_schemas/test_single_inheritance_multi_level.py b/src/exp2python/examples/unitary_schemas/test_single_inheritance_multi_level.py deleted file mode 100644 index d552f6add..000000000 --- a/src/exp2python/examples/unitary_schemas/test_single_inheritance_multi_level.py +++ /dev/null @@ -1,130 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_single_inheritance_multi_level' - -schema_scope = sys.modules[__name__] - -# Defined datatype length_measure -class length_measure(REAL): - def __init__(self,*kargs): - pass - -# Defined datatype label -class label(STRING): - def __init__(self,*kargs): - pass - -# Defined datatype point -class point(REAL): - def __init__(self,*kargs): - pass - - -#################### - # ENTITY shape # -#################### -class shape(BaseEntityClass): - '''Entity shape definition. - - :param item_name - :type item_name:label - - :param number_of_sides - :type number_of_sides:INTEGER - ''' - def __init__( self , item_name,number_of_sides, ): - self.item_name = item_name - self.number_of_sides = number_of_sides - - @apply - def item_name(): - def fget( self ): - return self._item_name - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument item_name is mantatory and can not be set to None') - if not check_type(value,label): - self._item_name = label(value) - else: - self._item_name = value - return property(**locals()) - - @apply - def number_of_sides(): - def fget( self ): - return self._number_of_sides - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument number_of_sides is mantatory and can not be set to None') - if not check_type(value,INTEGER): - self._number_of_sides = INTEGER(value) - else: - self._number_of_sides = value - return property(**locals()) - -#################### - # ENTITY subshape # -#################### -class subshape(shape): - '''Entity subshape definition. - ''' - def __init__( self , inherited0__item_name , inherited1__number_of_sides , ): - shape.__init__(self , inherited0__item_name , inherited1__number_of_sides , ) - -#################### - # ENTITY rectangle # -#################### -class rectangle(subshape): - '''Entity rectangle definition. - - :param height - :type height:length_measure - - :param width - :type width:length_measure - ''' - def __init__( self , inherited0__item_name , inherited1__number_of_sides , height,width, ): - subshape.__init__(self , inherited0__item_name , inherited1__number_of_sides , ) - self.height = height - self.width = width - - @apply - def height(): - def fget( self ): - return self._height - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument height is mantatory and can not be set to None') - if not check_type(value,length_measure): - self._height = length_measure(value) - else: - self._height = value - return property(**locals()) - - @apply - def width(): - def fget( self ): - return self._width - def fset( self, value ): - # Mandatory argument - if value==None: - raise AssertionError('Argument width is mantatory and can not be set to None') - if not check_type(value,length_measure): - self._width = length_measure(value) - else: - self._width = value - return property(**locals()) diff --git a/src/exp2python/examples/unitary_schemas/test_where_rule.py b/src/exp2python/examples/unitary_schemas/test_where_rule.py deleted file mode 100644 index 99bb2f146..000000000 --- a/src/exp2python/examples/unitary_schemas/test_where_rule.py +++ /dev/null @@ -1,51 +0,0 @@ -# This file was generated by exp2python. You probably don't want to edit -# it since your modifications will be lost if exp2python is used to -# regenerate it. -import sys - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Builtin import * -from SCL.Rules import * - -schema_name = 'test_where_rule' - -schema_scope = sys.modules[__name__] - -# Defined datatype month -class month(INTEGER): - def __init__(self,*kargs): - pass - self.unnamed_wr_0() - self.unnamed_wr_1() - - def unnamed_wr_0(self): - eval_unnamed_wr_0 = (self <= 12) - if not eval_unnamed_wr_0: - raise AssertionError('Rule unnamed_wr_0 violated') - else: - return eval_unnamed_wr_0 - - def unnamed_wr_1(self): - eval_unnamed_wr_1 = (self >= 1) - if not eval_unnamed_wr_1: - raise AssertionError('Rule unnamed_wr_1 violated') - else: - return eval_unnamed_wr_1 - -# Defined datatype positive -class positive(INTEGER): - def __init__(self,*kargs): - pass - self.notnegative() - - def notnegative(self): - eval_notnegative_wr = (self > 0) - if not eval_notnegative_wr: - raise AssertionError('Rule notnegative violated') - else: - return eval_notnegative_wr - diff --git a/src/exp2python/python/setup.py b/src/exp2python/python/LICENSE similarity index 81% rename from src/exp2python/python/setup.py rename to src/exp2python/python/LICENSE index bda974879..6e4fe3b3b 100644 --- a/src/exp2python/python/setup.py +++ b/src/exp2python/python/LICENSE @@ -1,9 +1,10 @@ -#!/usr/bin/env python - # Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com) +# Copyright (c) 2014, Christopher HORLER (cshorler@googlemail.com) +# Copyright (c) 2021, Devon Sparks (devonsparks.com) + # All rights reserved. -# This file is part StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -29,15 +30,4 @@ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -from distutils.core import setup - -setup(name='SCL', - version='0.5', - description='Python STEP Class Library', - author='Thomas Paviot', - author_email='tpaviot@gmail.com', - url='https://github.com/mpictor/StepClassLibrary', - packages=['SCL'], - ) \ No newline at end of file +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/src/exp2python/python/README.md b/src/exp2python/python/README.md new file mode 100644 index 000000000..20278a512 --- /dev/null +++ b/src/exp2python/python/README.md @@ -0,0 +1,22 @@ +# stepcode - A Python3 STEP Library + +STEPCODE Python is a Python3-based library for parsing and manipulating ISO 10303 Part 21 ("STEP") files. + +# Use + +To parse a ISO 10303 Part 21 file, use the `Parser` class of `stepcode.Part21`. On a successful parse, the result will be a Part 21 parse tree and associated STEP instances. + +See [test_parser](tests/test_parser.py) for use of the `stepcode.Part21` parser with a sample STEP file. + + +# Building + +The stepcode Python package can be built directly using [PyPA's build module](https://github.com/pypa/build). Run `python3 -m build` from this directory. + +# Testing + +STEPCODE Python comes with a small test suite (additions welcome!) From this directory, `python3 -m unittest discover`. + +# License + +See [LICENSE](LICENSE) \ No newline at end of file diff --git a/src/exp2python/python/pyproject.toml b/src/exp2python/python/pyproject.toml new file mode 100644 index 000000000..8d4a680fe --- /dev/null +++ b/src/exp2python/python/pyproject.toml @@ -0,0 +1,6 @@ +[build-system] +requires = [ + "setuptools>=40", + "wheel" +] +build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/src/exp2python/python/setup.cfg b/src/exp2python/python/setup.cfg new file mode 100644 index 000000000..3a05fbf27 --- /dev/null +++ b/src/exp2python/python/setup.cfg @@ -0,0 +1,22 @@ +[metadata] +name = stepcode +version = 0.7.0 +author = Thomas Paviot , Christopher HORLER (cshorler@googlemail.com), Devon Sparks (devonsparks.com) +description = stepcode is a Python3-based library for parsing and manipulating ISO 10303 Part 21 ("STEP") files. +long_description = file: README.md +long_description_content_type = text/markdown + +url = https://github.com/stepcode/stepcode +project_urls = + Bug Tracker = https://github.com/stepcode/stepcode/issues +classifiers = + Programming Language :: Python :: 3 + +[options] +package_dir = + =. +packages = stepcode +python_requires = >=3.6 +install_requires = + ply + diff --git a/src/exp2python/python/SCL/AggregationDataTypes.py b/src/exp2python/python/stepcode/AggregationDataTypes.py similarity index 95% rename from src/exp2python/python/SCL/AggregationDataTypes.py rename to src/exp2python/python/stepcode/AggregationDataTypes.py index 9bb4709e8..9dfd1b1a0 100644 --- a/src/exp2python/python/SCL/AggregationDataTypes.py +++ b/src/exp2python/python/stepcode/AggregationDataTypes.py @@ -1,7 +1,7 @@ # Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com) # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -29,11 +29,11 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from SimpleDataTypes import * -from TypeChecker import check_type -import BaseType +from .SimpleDataTypes import * +from .TypeChecker import check_type +from . import BaseType -class BaseAggregate(object): +class BaseAggregate: """ A class that define common properties to ARRAY, LIST, SET and BAG. """ def __init__( self , bound1 , bound2 , base_type ): @@ -126,9 +126,9 @@ class ARRAY(BaseType.Type, BaseType.Aggregate): """ def __init__( self , bound_1 , bound_2 , base_type , UNIQUE = False, OPTIONAL=False, scope = None): BaseType.Type.__init__(self, base_type, scope) - if not type(bound_1)==int: + if not isinstance(bound_1, int): raise TypeError("ARRAY lower bound must be an integer") - if not type(bound_2)==int: + if not isinstance(bound_2, int): raise TypeError("ARRAY upper bound must be an integer") if not (bound_1 <= bound_2): raise AssertionError("ARRAY lower bound must be less than or equal to upper bound") @@ -179,7 +179,7 @@ def __getitem__(self, index): raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound_2,index)) else: value = self._container[index-self._bound_1] - if not self._optional and value==None: + if not self._optional and value is None: raise AssertionError("Not OPTIONAL prevent the value with index %i from being None (default). Please set the value first."%index) return value @@ -235,17 +235,17 @@ class LIST(BaseType.Type, BaseType.Aggregate): """ def __init__( self , bound_1 , bound_2 , base_type , UNIQUE = False, scope = None): BaseType.Type.__init__(self, base_type, scope) - if not type(bound_1)==int: + if not isinstance(bound_1, int): raise TypeError("LIST lower bound must be an integer") # bound_2 can be set to None self._unbounded = False - if bound_2 == None: + if bound_2 is None: self._unbounded = True - elif not type(bound_2)==int: + elif not isinstance(bound_2, int): raise TypeError("LIST upper bound must be an integer") if not bound_1>=0: raise AssertionError("LIST lower bound must be greater of equal to 0") - if (type(bound_2)==int and not (bound_1 <= bound_2)): + if (isinstance(bound_2, int) and not (bound_1 <= bound_2)): raise AssertionError("ARRAY lower bound must be less than or equal to upper bound") # set up class attributes self._bound_1 = bound_1 @@ -282,14 +282,14 @@ def get_loindex(self): def get_hibound(self): hibound = self._bound_2 - if type(hibound)==int: + if isinstance(hibound, int): return INTEGER(hibound) else: return hibound def get_lobound(self): lobound = self._bound_1 - if type(lobound)==int: + if isinstance(lobound, int): return INTEGER(lobound) else: return lobound @@ -313,7 +313,7 @@ def __getitem__(self, index): raise IndexError("ARRAY index out of bound (upper bound is %i, passed %i)"%(self._bound_2,index)) else: value = self._container[index-self._bound_1] - if value == None: + if value is None: raise AssertionError("Value with index %i not defined. Please set the value first."%index) return value #case unbounded @@ -322,7 +322,7 @@ def __getitem__(self, index): raise AssertionError("Value with index %i not defined. Please set the value first."%index) else: value = self._container[index-self._bound_1] - if value == None: + if value is None: raise AssertionError("Value with index %i not defined. Please set the value first."%index) return value @@ -409,17 +409,17 @@ class BAG(BaseType.Type, BaseType.Aggregate): """ def __init__( self , bound_1 , bound_2 , base_type , scope = None): BaseType.Type.__init__(self, base_type, scope) - if not type(bound_1)==int: + if not isinstance(bound_1, int): raise TypeError("LIST lower bound must be an integer") # bound_2 can be set to None self._unbounded = False - if bound_2 == None: + if bound_2 is None: self._unbounded = True - elif not type(bound_2)==int: + elif not isinstance(bound_2, int): raise TypeError("LIST upper bound must be an integer") if not bound_1>=0: raise AssertionError("LIST lower bound must be greater of equal to 0") - if (type(bound_2)==int and not (bound_1 <= bound_2)): + if (isinstance(bound_2, int) and not (bound_1 <= bound_2)): raise AssertionError("ARRAY lower bound must be less than or equal to upper bound") # set up class attributes self._bound_1 = bound_1 @@ -462,14 +462,14 @@ def get_loindex(self): def get_hibound(self): hibound = self._bound_2 - if type(hibound)==int: + if isinstance(hibound, int): return INTEGER(hibound) else: return hibound def get_lobound(self): lobound = self._bound_1 - if type(lobound)==int: + if isinstance(lobound, int): return INTEGER(lobound) else: return lobound @@ -527,17 +527,17 @@ class SET(BaseType.Type, BaseType.Aggregate): """ def __init__( self , bound_1 , bound_2 , base_type , scope = None): BaseType.Type.__init__(self, base_type, scope) - if not type(bound_1)==int: + if not isinstance(bound_1, int): raise TypeError("LIST lower bound must be an integer") # bound_2 can be set to None self._unbounded = False - if bound_2 == None: + if bound_2 is None: self._unbounded = True - elif not type(bound_2)==int: + elif not isinstance(bound_2, int): raise TypeError("LIST upper bound must be an integer") if not bound_1>=0: raise AssertionError("LIST lower bound must be greater of equal to 0") - if (type(bound_2)==int and not (bound_1 <= bound_2)): + if (isinstance(bound_2, int) and not (bound_1 <= bound_2)): raise AssertionError("ARRAY lower bound must be less than or equal to upper bound") # set up class attributes self._bound_1 = bound_1 @@ -581,14 +581,14 @@ def get_loindex(self): def get_hibound(self): hibound = self._bound_2 - if type(hibound)==int: + if isinstance(hibound, int): return INTEGER(hibound) else: return hibound def get_lobound(self): lobound = self._bound_1 - if type(lobound)==int: + if isinstance(lobound, int): return INTEGER(lobound) else: return lobound diff --git a/src/exp2python/python/SCL/BaseType.py b/src/exp2python/python/stepcode/BaseType.py similarity index 91% rename from src/exp2python/python/SCL/BaseType.py rename to src/exp2python/python/stepcode/BaseType.py index 0698ba89b..64bf779f2 100644 --- a/src/exp2python/python/SCL/BaseType.py +++ b/src/exp2python/python/stepcode/BaseType.py @@ -1,7 +1,7 @@ # Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com) # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -29,7 +29,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -class Type(object): +class Type: ''' A type can be defined from its name and scope Looking into the scope dict returns the python type class. @@ -43,10 +43,10 @@ def get_scope(self): return self._scope def get_type(self): - if type(self._typedef) == str: - if self._scope == None: + if isinstance(self._typedef, str): + if self._scope is None: raise AssertionError('No scope defined for this type') - elif vars(self._scope).has_key(self._typedef): + elif self._typedef in vars(self._scope): return vars(self._scope)[self._typedef] else: raise TypeError("Type '%s' is not defined in given scope"%self._typedef) @@ -65,5 +65,5 @@ class Aggregate: class line: pass new_type = Type('lie',scp) - print new_type.get_type() + print(new_type.get_type()) \ No newline at end of file diff --git a/src/exp2python/python/SCL/Builtin.py b/src/exp2python/python/stepcode/Builtin.py similarity index 98% rename from src/exp2python/python/SCL/Builtin.py rename to src/exp2python/python/stepcode/Builtin.py index e0a20e0b8..0d71466a1 100644 --- a/src/exp2python/python/SCL/Builtin.py +++ b/src/exp2python/python/stepcode/Builtin.py @@ -1,7 +1,7 @@ # Copyright (c) 2011-2012, Thomas Paviot (tpaviot@gmail.com) # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -32,9 +32,9 @@ __doc__ = "This module defines EXPRESS built in constants and functions" import math -from SimpleDataTypes import * -from BaseType import Aggregate -from AggregationDataTypes import * +from .SimpleDataTypes import * +from .BaseType import Aggregate +from .AggregationDataTypes import * SCL_float_epsilon = 1e-7 # Builtin constants @@ -220,7 +220,7 @@ def SIN(V): #Result : true or false depending on whether V has an actual or indeterminate (?) value. #EXAMPLE 131 { IF EXISTS ( a ) THEN ... def EXISTS(V): - if V==None: + if V is None: return False else: return True @@ -536,7 +536,7 @@ def ODD(V): # Python note: # @TODO: implement the ROLESOF function def ROLESOF(V): - raise NotImplemented("Function ROLESOF not implemented") + raise NotImplementedError("Function ROLESOF not implemented") # EXPRESS definition: # =================== @@ -580,7 +580,7 @@ def SQRT(V): # =================== #15.24 Tan - arithmetic function #FUNCTION TAN ( V:NUMBER ) : REAL; -#The tan function returns the tangent of of an angle. +#The tan function returns the tangent of an angle. #Parameters : V is a number representing an angle expressed in radians. #Result : The tangent of the angle. If the angle is npi/2, where n is an odd integer, indeterminate #(?) is returned. @@ -639,7 +639,7 @@ def TYPEOF(V): #The usedin function returns each entity instance that uses a specified entity instance in a #specified role. def USEDIN(T,R): - raise NotImplemented("USEDIN function not yet implemented.") + raise NotImplementedError("USEDIN function not yet implemented.") # EXPRESS definition: # =================== @@ -691,7 +691,7 @@ def VALUE(V): def VALUE_IN(C,V): if not isinstance(C,Aggregate): raise TypeError("VALUE_IN method takes an aggregate as first parameter") - raise NotImplemented("VALUE_IN function not yet implemented") + raise NotImplementedError("VALUE_IN function not yet implemented") # EXPRESS definition: # =================== @@ -713,4 +713,4 @@ def VALUE_UNIQUE(V): raise TypeError("VALUE_UNIQUE method takes an aggregate as first parameter") return V.get_value_unique() - \ No newline at end of file + diff --git a/src/exp2python/python/SCL/ConstructedDataTypes.py b/src/exp2python/python/stepcode/ConstructedDataTypes.py similarity index 95% rename from src/exp2python/python/SCL/ConstructedDataTypes.py rename to src/exp2python/python/stepcode/ConstructedDataTypes.py index 4959704fc..9b9d8bc5e 100644 --- a/src/exp2python/python/SCL/ConstructedDataTypes.py +++ b/src/exp2python/python/stepcode/ConstructedDataTypes.py @@ -1,7 +1,7 @@ # Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com) # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -29,9 +29,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import sys from enum import Enum -import BaseType +from . import BaseType class ENUMERATION(Enum): """ @@ -59,14 +58,14 @@ class ENUMERATION(Enum): """ pass -class SELECT(object): +class SELECT: """ A select data type has as its domain the union of the domains of the named data types in its select list. The select data type is a generalization of each of the named data types in its select list. """ def __init__(self,*kargs,**args): # first defining the scope - if args.has_key('scope'): + if 'scope' in args: self._scope = args['scope'] else: self._scope = None @@ -84,7 +83,7 @@ def get_allowed_types(self): def get_allowed_basic_types(self): ''' if a select contains some subselect, goes down through the different - sublayers untill there is no more ''' + sublayers until there is no more ''' b = [] _auth_types = self.get_allowed_types() for _auth_type in _auth_types: diff --git a/src/exp2python/python/SCL/Model.py b/src/exp2python/python/stepcode/Model.py similarity index 95% rename from src/exp2python/python/SCL/Model.py rename to src/exp2python/python/stepcode/Model.py index 9a3f0e87b..0a2d20aca 100644 --- a/src/exp2python/python/SCL/Model.py +++ b/src/exp2python/python/stepcode/Model.py @@ -1,7 +1,7 @@ # Copyright (c) 2011-2012, Thomas Paviot (tpaviot@gmail.com) # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -29,11 +29,11 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -class Model(objet): +class Model: """ The container for entity instances """ def __init_(self): - print "Model initialized" + print("Model initialized") self._instances = [] def add_instance(self, entity_instance): diff --git a/src/exp2python/python/SCL/Part21.py b/src/exp2python/python/stepcode/Part21.py similarity index 71% rename from src/exp2python/python/SCL/Part21.py rename to src/exp2python/python/stepcode/Part21.py index 3490b55bf..8c8be8fef 100644 --- a/src/exp2python/python/SCL/Part21.py +++ b/src/exp2python/python/stepcode/Part21.py @@ -6,7 +6,7 @@ # # All rights reserved. # -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -41,19 +41,6 @@ from ply.lex import LexError logger = logging.getLogger(__name__) - -# ensure Python 2.6 compatibility -if not hasattr(logging, 'NullHandler'): - class NullHandler(logging.Handler): - def handle(self, record): - pass - def emit(self, record): - pass - def createLock(self): - self.lock = None - - setattr(logging, 'NullHandler', NullHandler) - logger.addHandler(logging.NullHandler()) #################################################################################################### @@ -66,19 +53,19 @@ def createLock(self): #################################################################################################### # Lexer #################################################################################################### -class Lexer(object): +class Lexer: tokens = list(base_tokens) states = (('slurp', 'exclusive'),) - def __init__(self, debug=0, optimize=0, compatibility_mode=False, header_limit=4096): + def __init__(self, debug=False, optimize=False, compatibility_mode=False, header_limit=4096): self.base_tokens = list(base_tokens) self.schema_dict = {} self.active_schema = {} self.input_length = 0 self.compatibility_mode = compatibility_mode self.header_limit = header_limit - self.lexer = lex.lex(module=self, debug=debug, debuglog=logger, optimize=optimize, - errorlog=logger) + self.lexer = lex.lex(module=self, debug=debug, optimize=optimize, lextab='l21tab', + debuglog=logger, errorlog=logger) self.reset() def __getattr__(self, name): @@ -98,10 +85,7 @@ def reset(self): self.lexer.begin('slurp') def token(self): - try: - return next(self.lexer) - except StopIteration: - return None + return self.lexer.token() def activate_schema(self, schema_name): if schema_name in self.schema_dict: @@ -138,6 +122,9 @@ def t_slurp_error(self, t): t.lexer.lineno += t.value[0:offset].count('\n') t.lexer.skip(offset) + def t_error(self, t): + raise LexError("Scanning error, invalid input", "{0}...".format(t.value[0:20])) + # Comment (ignored) def t_COMMENT(self, t): r'/\*(.|\n)*?\*/' @@ -206,8 +193,8 @@ def t_BINARY(self, t): # Punctuation literals = '()=;,*$' - t_ANY_ignore = ' \t' - + t_ANY_ignore = ' \t\r' + #################################################################################################### # Simple Model @@ -225,24 +212,24 @@ def __init__(self, file_description, file_name, file_schema): self.extra_headers = [] class HeaderEntity: - def __init__(self, type_name, *params): + def __init__(self, type_name, params): self.type_name = type_name - self.params = list(params) if params else [] + self.params = params class Section: def __init__(self, entities): self.entities = entities class SimpleEntity: - def __init__(self, ref, type_name, *params): + def __init__(self, ref, type_name, params): self.ref = ref self.type_name = type_name - self.params = list(params) if params else [] + self.params = params class ComplexEntity: - def __init__(self, ref, *params): + def __init__(self, ref, params): self.ref = ref - self.params = list(params) if params else [] + self.params = params class TypedParameter: def __init__(self, type_name, *params): @@ -252,17 +239,23 @@ def __init__(self, type_name, *params): #################################################################################################### # Parser #################################################################################################### -class Parser(object): +class Parser: tokens = list(base_tokens) - start = 'exchange_file' - def __init__(self, lexer=None, debug=0): - self.lexer = lexer if lexer else Lexer() - + def __init__(self, lexer=None, debug=False, tabmodule=None, start=None, optimize=False): + # defaults + start_tabs = {'exchange_file': 'p21tab', 'extract_header': 'p21hdrtab'} + if start and tabmodule: start_tabs[start] = tabmodule + if not start: start = 'exchange_file' + if start not in start_tabs: raise ValueError('please pass (dedicated) tabmodule') + + # lexer may provide a more specialised set of tokens for use in (subclassed) parser try: self.tokens = lexer.tokens except AttributeError: pass - self.parser = yacc.yacc(module=self, debug=debug, debuglog=logger, errorlog=logger) + self.lexer = lexer if lexer else Lexer() + self.parser = yacc.yacc(debug=debug, module=self, tabmodule=start_tabs[start], start=start, + optimize=optimize, debuglog=logger, errorlog=logger) self.reset() def parse(self, p21_data, **kwargs): @@ -272,7 +265,7 @@ def parse(self, p21_data, **kwargs): if 'debug' in kwargs: result = self.parser.parse(lexer=self.lexer, debug=logger, - ** dict((k, v) for k, v in kwargs.iteritems() if k != 'debug')) + ** dict((k, v) for k, v in kwargs.items() if k != 'debug')) else: result = self.parser.parse(lexer=self.lexer, **kwargs) return result @@ -284,6 +277,12 @@ def reset(self): def p_exchange_file(self, p): """exchange_file : check_p21_start_token header_section data_section_list check_p21_end_token""" p[0] = P21File(p[2], p[3]) + + def p_extract_header(self, p): + """extract_header : check_p21_start_token header_section DATA""" + p[0] = P21File(p[2], []) + # clear input to avoid trailing context errors + p.lexer.input('') def p_check_start_token(self, p): """check_p21_start_token : PART21_START""" @@ -323,9 +322,8 @@ def p_simple_entity_instance(self, p): p[0] = SimpleEntity(p[1], *p[3]) def p_entity_instance_error(self, p): - """simple_entity_instance : error '=' simple_record ';' - complex_entity_instance : error '=' subsuper_record ';'""" - pass + """entity_instance : check_entity_instance_name '=' error ';'""" + logger.error('resyncing parser, check input between lineno %d and %d', p.lineno(2), p.lineno(4)) def p_complex_entity_instance(self, p): """complex_entity_instance : check_entity_instance_name '=' subsuper_record ';'""" @@ -333,25 +331,34 @@ def p_complex_entity_instance(self, p): def p_subsuper_record(self, p): """subsuper_record : '(' simple_record_list ')'""" - p[0] = [TypedParameter(*x) for x in p[2]] + p[0] = [SimpleEntity(None, *x) for x in p[2]] + def p_data_section_list_init(self, p): + """data_section_list : data_section""" + p[0] = [p[1],] + def p_data_section_list(self, p): - """data_section_list : data_section_list data_section - | data_section""" - try: p[0] = p[1] + [p[2],] - except IndexError: p[0] = [p[1],] + """data_section_list : data_section_list data_section""" + p[0] = p[1] + p[0].append(p[2]) + def p_header_entity_list_init(self, p): + """header_entity_list : header_entity""" + p[0] = [p[1],] + def p_header_entity_list(self, p): - """header_entity_list : header_entity_list header_entity - | header_entity""" - try: p[0] = p[1] + [p[2],] - except IndexError: p[0] = [p[1],] + """header_entity_list : header_entity_list header_entity""" + p[0] = p[1] + p[0].append(p[2]) + def p_parameter_list_init(self, p): + """parameter_list : parameter""" + p[0] = [p[1],] + def p_parameter_list(self, p): - """parameter_list : parameter_list ',' parameter - | parameter""" - try: p[0] = p[1] + [p[3],] - except IndexError: p[0] = [p[1],] + """parameter_list : parameter_list ',' parameter""" + p[0] = p[1] + p[0].append(p[3]) def p_keyword(self, p): """keyword : USER_DEFINED_KEYWORD @@ -385,7 +392,7 @@ def p_parameter_empty_list(self, p): def p_data_start(self, p): """data_start : DATA '(' parameter_list ')' ';'""" - pass + pass # TODO: do something with the parameters def p_data_start_empty(self, p): """data_start : DATA '(' ')' ';' @@ -396,11 +403,14 @@ def p_data_section(self, p): """data_section : data_start entity_instance_list ENDSEC""" p[0] = Section(p[2]) + def p_entity_instance_list_init(self, p): + """entity_instance_list : entity_instance""" + p[0] = [p[1],] + def p_entity_instance_list(self, p): - """entity_instance_list : entity_instance_list entity_instance - | entity_instance""" - try: p[0] = p[1] + [p[2],] - except IndexError: p[0] = [p[1],] + """entity_instance_list : entity_instance_list entity_instance""" + p[0] = p[1] + p[0].append(p[2]) def p_entity_instance_list_empty(self, p): """entity_instance_list : empty""" @@ -420,18 +430,41 @@ def p_simple_record_with_params(self, p): """simple_record : keyword '(' parameter_list ')'""" p[0] = (p[1], p[3]) + def p_simple_record_list_init(self, p): + """simple_record_list : simple_record""" + p[0] = [p[1],] + def p_simple_record_list(self, p): - """simple_record_list : simple_record_list simple_record - | simple_record""" - try: p[0] = p[1] + [p[2],] - except IndexError: p[0] = [p[1],] + """simple_record_list : simple_record_list simple_record""" + p[0] = p[1] + p[0].append(p[2]) def p_empty(self, p): """empty :""" pass -def test_debug(): - import os.path + +def debug_lexer(): + import codecs + from os.path import normpath, expanduser + + logging.basicConfig() + logger.setLevel(logging.DEBUG) + + lexer = Lexer(debug=True) + + p = normpath(expanduser('~/projects/src/stepcode/data/ap209/ATS7-out.stp')) + with codecs.open(p, 'r', encoding='iso-8859-1') as f: + s = f.read() + lexer.input(s) + while True: + tok = lexer.token() + if not tok: break + print(tok) + +def debug_parser(): + import codecs + from os.path import normpath, expanduser logging.basicConfig() logger.setLevel(logging.DEBUG) @@ -440,36 +473,73 @@ def test_debug(): parser.reset() logger.info("***** parser debug *****") - p = os.path.expanduser('~/projects/src/stepcode/data/ap214e3/s1-c5-214/s1-c5-214.stp') - with open(p, 'rU') as f: + p = normpath(expanduser('~/projects/src/stepcode/data/ap214e3/s1-c5-214/s1-c5-214.stp')) + with codecs.open(p, 'r', encoding='iso-8859-1') as f: s = f.read() - try: - parser.parse(s, debug=1) - except SystemExit: - pass + parser.parse(s, debug=1) logger.info("***** finished *****") def test(): - import os, os.path, itertools, codecs + import os, codecs + from os.path import normpath, expanduser logging.basicConfig() logger.setLevel(logging.INFO) + + lexer = Lexer(optimize=True) + parser = Parser(lexer=lexer, optimize=True) + compat_list = [] - parser = Parser() + def parse_check(p): + logger.info("processing {0}".format(p)) + parser.reset() + with codecs.open(p, 'r', encoding='iso-8859-1') as f: + s = f.read() + parser.parse(s) + + logger.info("***** standard test *****") + stepcode_dir = normpath(os.path.expanduser('~/projects/src/stepcode')) + for d, _, files in os.walk(stepcode_dir): + for f in filter(lambda x: x.endswith('.stp'), files): + p = os.path.join(d, f) + try: + parse_check(p) + except LexError: + logger.exception('Lexer issue, adding {0} to compatibility test list'.format(os.path.basename(p))) + compat_list.append(p) + + lexer = Lexer(optimize=True, compatibility_mode=True) + parser = Parser(lexer=lexer, optimize=True) + + logger.info("***** compatibility test *****") + for p in compat_list: + parse_check(p) + + logger.info("***** finished *****") + +def test_header_only(): + import os, codecs + from os.path import normpath, expanduser + + logging.basicConfig() + logger.setLevel(logging.INFO) + + lexer = Lexer(optimize=True) + parser = Parser(start='extract_header', optimize=True) compat_list = [] def parse_check(p): logger.info("processing {0}".format(p)) parser.reset() - with open(p, 'rU') as f: - iso_wrapper = codecs.EncodedFile(f, 'iso-8859-1') - s = iso_wrapper.read() + with codecs.open(p, 'r', encoding='iso-8859-1') as f: + s = f.read() parser.parse(s) logger.info("***** standard test *****") - for d, _, files in os.walk(os.path.expanduser('~/projects/src/stepcode')): - for f in itertools.ifilter(lambda x: x.endswith('.stp'), files): + stepcode_dir = normpath(os.path.expanduser('~/projects/src/stepcode')) + for d, _, files in os.walk(stepcode_dir): + for f in filter(lambda x: x.endswith('.stp'), files): p = os.path.join(d, f) try: parse_check(p) @@ -477,8 +547,8 @@ def parse_check(p): logger.exception('Lexer issue, adding {0} to compatibility test list'.format(os.path.basename(p))) compat_list.append(p) - lexer = Lexer(compatibility_mode=True) - parser = Parser(lexer=lexer) + lexer = Lexer(optimize=True, compatibility_mode=True) + parser = Parser(lexer=lexer, start='extract_header', optimize=True) logger.info("***** compatibility test *****") for p in compat_list: @@ -487,4 +557,7 @@ def parse_check(p): logger.info("***** finished *****") if __name__ == '__main__': + #debug_lexer() + #debug_parser() test() + #test_header_only() diff --git a/src/exp2python/python/SCL/Rules.py b/src/exp2python/python/stepcode/Rules.py similarity index 95% rename from src/exp2python/python/SCL/Rules.py rename to src/exp2python/python/stepcode/Rules.py index 1267a99d6..4c01e15a0 100644 --- a/src/exp2python/python/SCL/Rules.py +++ b/src/exp2python/python/stepcode/Rules.py @@ -1,7 +1,7 @@ # Copyright (c) 2011-2012, Thomas Paviot (tpaviot@gmail.com) # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -31,7 +31,7 @@ __doc__ = "This module defines EXPRESS rules" -class Rule(object): +class Rule: ''' This class describes a RULE @TODO: to be implemented diff --git a/src/exp2python/python/SCL/SCLBase.py b/src/exp2python/python/stepcode/SCLBase.py similarity index 91% rename from src/exp2python/python/SCL/SCLBase.py rename to src/exp2python/python/stepcode/SCLBase.py index 617c816ad..aebc880f3 100644 --- a/src/exp2python/python/SCL/SCLBase.py +++ b/src/exp2python/python/stepcode/SCLBase.py @@ -1,7 +1,8 @@ # Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com) +# Copyright (c) 2022, Chris Horler (cshorler@googlemail.com) # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -29,7 +30,12 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -class BaseEntityClass(object): +__all__ = ['BaseEntityClass'] + +def raise_(exc): + raise exc + +class BaseEntityClass: """ A class that allows advanced __repr__ features for entity instances """ def __repr__(self): diff --git a/src/exp2python/python/SCL/SimpleDataTypes.py b/src/exp2python/python/stepcode/SimpleDataTypes.py similarity index 94% rename from src/exp2python/python/SCL/SimpleDataTypes.py rename to src/exp2python/python/stepcode/SimpleDataTypes.py index e7075aa41..4e1d0a508 100644 --- a/src/exp2python/python/SCL/SimpleDataTypes.py +++ b/src/exp2python/python/stepcode/SimpleDataTypes.py @@ -1,7 +1,7 @@ # Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com) # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -116,7 +116,7 @@ class STRING(str): 318 width_spec = '(' width ')' [ FIXED ] . 317 width = numeric_expression . A string data type may be defined as either fixed or varying width (number of characters). If - it is not specfically defined as fixed width (by using the fixed reserved word in the dfinition) + it is not specifically defined as fixed width (by using the fixed reserved word in the definition) the string has varying width. The domain of a fixed width string data type is the set of all character sequences of exactly @@ -185,7 +185,7 @@ def __init__(self, value, width=-1, fixed=False): self._fixed = fixed # Check implicit width if (width!=-1) and not fixed: - raise ValueError("The 'width' parameter is passed but 'fixed' is still false. Please explicitely set 'fixed' to True to avoid implicit declaration") + raise ValueError("The 'width' parameter is passed but 'fixed' is still false. Please explicitly set 'fixed' to True to avoid implicit declaration") # First check the string length if 'fixed' is set to True if fixed: if len(value) != width: @@ -198,19 +198,19 @@ def __init__(self, value, width=-1, fixed=False): if __name__=="__main__": - print "Creating REAL from float value" + print("Creating REAL from float value") a = REAL(1.5) - print a*2 - print "Creating REAL from string value" + print(a*2) + print("Creating REAL from string value") a = REAL("1.2") - print a*3 - print "Creating INTEGER from int value" + print(a*3) + print("Creating INTEGER from int value") b = INTEGER(2) c = INTEGER(3) - print b+c - print "Creating INTEGER from string value" + print(b+c) + print("Creating INTEGER from string value") e = INTEGER("5") f = INTEGER("8") - print e*f + print(e*f) \ No newline at end of file diff --git a/src/exp2python/python/SCL/TypeChecker.py b/src/exp2python/python/stepcode/TypeChecker.py similarity index 89% rename from src/exp2python/python/SCL/TypeChecker.py rename to src/exp2python/python/stepcode/TypeChecker.py index 2c04faed5..c97d7c11f 100644 --- a/src/exp2python/python/SCL/TypeChecker.py +++ b/src/exp2python/python/stepcode/TypeChecker.py @@ -1,7 +1,7 @@ # Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com) # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -29,8 +29,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from ConstructedDataTypes import ENUMERATION, SELECT -import BaseType +from .ConstructedDataTypes import ENUMERATION, SELECT +from . import BaseType RAISE_EXCEPTION_IF_TYPE_DOES_NOT_MATCH = True DEBUG = False @@ -40,20 +40,20 @@ def cast_python_object_to_aggregate(obj, aggregate): [1.,2.,3.]-> ARRAY(1,3,REAL)""" aggregate_lower_bound = aggregate.bound_1() aggregate_upper_bound = aggregate.bound_2() - if type(obj)==list: + if isinstance(obj, list): for idx in range(aggregate_lower_bound,aggregate_upper_bound+1): aggregate[idx] = obj[idx-aggregate_lower_bound] return aggregate def check_type(instance, expected_type): - """ This function checks wether an object is an instance of a given class + """ This function checks whether an object is an instance of a given class returns False or True """ type_match = False #by default, will be set to True if any match if DEBUG: - print "===" - print "Instance passed: ",instance - print "Expected type: ", expected_type + print("===") + print("Instance passed: ",instance) + print("Expected type: ", expected_type) # in the case of an enumeration, we have to check if the instance is in the list if (isinstance(expected_type,ENUMERATION)): allowed_ids = expected_type.get_enum_ids() @@ -71,11 +71,11 @@ def check_type(instance, expected_type): if RAISE_EXCEPTION_IF_TYPE_DOES_NOT_MATCH: raise TypeError('Argument type must be %s (you passed %s)'%(allowed_types,type(instance))) else: - print "WARNING: expected '%s' but passed a '%s', casting from python value to EXPRESS type"%(allowed_types, type(instance)) + print("WARNING: expected '%s' but passed a '%s', casting from python value to EXPRESS type"%(allowed_types, type(instance))) return False elif (isinstance(expected_type, BaseType.Aggregate)): # first check that they are instance of the same class - if not (type(instance) == type(expected_type)): + if not (isinstance(instance, type(expected_type))): raise TypeError('Expected %s but passed %s'%(type(expected_type),type(instance))) # then check that the base type is the same elif not (instance.get_type() == expected_type.get_type()): @@ -96,6 +96,6 @@ def check_type(instance, expected_type): if RAISE_EXCEPTION_IF_TYPE_DOES_NOT_MATCH: raise TypeError('Argument type must be %s (you passed %s)'%(expected_type,type(instance))) else: - print "WARNING: expected '%s' but passed a '%s', casting from python value to EXPRESS type"%(expected_type, type(instance)) + print("WARNING: expected '%s' but passed a '%s', casting from python value to EXPRESS type"%(expected_type, type(instance))) return False return True diff --git a/src/exp2python/python/SCL/Utils.py b/src/exp2python/python/stepcode/Utils.py similarity index 88% rename from src/exp2python/python/SCL/Utils.py rename to src/exp2python/python/stepcode/Utils.py index 7cce22494..76e352fc3 100644 --- a/src/exp2python/python/SCL/Utils.py +++ b/src/exp2python/python/stepcode/Utils.py @@ -1,7 +1,9 @@ # Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com) +# Copyright (c) 2021, Devon Sparks (devonsparks.com) + # All rights reserved. -# This file is part of the StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -61,10 +63,10 @@ def process_nested_parent_str(attr_str,idx=0): return params,k if __name__=="__main__": - print process_nested_parent_str2("'A'")[0] - print process_nested_parent_str2("30.0,0.0,5.0")[0] - print process_nested_parent_str2("1,2,(3,4,5),6,7,8")[0] - print process_nested_parent_str2("(#9149,#9166),#9142,.T.")[0] + print(process_nested_parent_str("'A'")[0]) + print(process_nested_parent_str("30.0,0.0,5.0")[0]) + print(process_nested_parent_str("1,2,(3,4,5),6,7,8")[0]) + print(process_nested_parent_str("(#9149,#9166),#9142,.T.")[0]) diff --git a/src/exp2python/python/SCL/__init__.py b/src/exp2python/python/stepcode/__init__.py similarity index 55% rename from src/exp2python/python/SCL/__init__.py rename to src/exp2python/python/stepcode/__init__.py index ebced4874..0bb38afaa 100644 --- a/src/exp2python/python/SCL/__init__.py +++ b/src/exp2python/python/stepcode/__init__.py @@ -1 +1 @@ -__all__ = ['SCLBase','SimpleDataTypes','AggregationDataTypes','TypeChecker','ConstructedDataTypes','Expr','Part21'] +__all__ = ['SCLBase','SimpleDataTypes','AggregationDataTypes','TypeChecker','ConstructedDataTypes','Part21'] diff --git a/src/exp2python/python/stepcode/_cPart21.c b/src/exp2python/python/stepcode/_cPart21.c new file mode 100644 index 000000000..2b93ac7ca --- /dev/null +++ b/src/exp2python/python/stepcode/_cPart21.c @@ -0,0 +1,4694 @@ +/* Generated by re2c 1.2.1 on Mon May 18 17:14:55 2020 */ +/* + * STEP Part 21 Parser + * + * Copyright (c) 2020, Christopher HORLER (cshorler@googlemail.com) + * + * All rights reserved. + * + * This file is part of the STEPCODE project. + * + * 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. + * + * Neither the name of the nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define YYCTYPE unsigned char +#define YYCURSOR in->cur +#define YYLIMIT in->lim +#define YYMARKER in->mrk +#define YYCTXMARKER in->ctxmrk +#define YYFILL(n) do { \ + if (fill(in, n) != 0) { \ + fprintf(stderr, "lexer fill(...) failed, exiting\n"); \ + exit(1); \ + } \ + } while (0) + +#define YYMAXFILL 17 + +#define INIT_BUF_SZ 4096 +#define INIT_STACK_SZ 64 + +/* reserved literals '(' ')' ';' '=' */ +#define T_P21_START 'S' +#define T_P21_END 'X' +#define T_HEADER 'H' +#define T_DATA 'D' +#define T_ENDSEC 'E' +#define T_EID 'I' +#define T_KEYWORD 'K' +#define T_VARIANT 'V' +#define T_EOF '\x00' +#define T_ERROR '\x01' + +#define V_REAL 'r' +#define V_INTEGER 'i' +#define V_STRING 's' +#define V_BINARY 'b' +#define V_ENUMERATION 'e' +#define V_EID T_EID +#define V_DERIVED '*' +#define V_EMPTY '$' + +#define P_FILE 'f' +#define P_HEADERSECTION 'h' +#define P_DATASECTION 'd' +#define P_HEADERENTITY 'x' +#define P_SIMPLEENTITY 's' +#define P_COMPLEXENTITY 'c' +#define P_SIMPLERECORD 'u' +#define P_LIST 'l' +#define P_PARAMETER 'p' + +int debug = 1; +#define dprintf(fmt, ...) \ + do { if (debug) fprintf(stderr, "%s:%3d " fmt, __FILE__, __LINE__, ##__VA_ARGS__); } while (0) + +/* ppfu https://stackoverflow.com/a/11763277/1162349 */ +#define GET_MACRO(_1, _2, _3, _4, NAME, ...) NAME +#define _EXPAND(x) x + +/* for lookahead */ +#define PUSH_SYMBOL(...) _EXPAND(GET_MACRO(__VA_ARGS__, _4, _3, _PUSH_SYMBOL2, _PUSH_SYMBOL1)(__VA_ARGS__)) +#define _PUSH_SYMBOL1(token) in->sym[in->nsym++] = (Symbol){(token), 0, n, in->lineno, in->sp - in->basemrk} +#define _PUSH_SYMBOL2(token, vtype) in->sym[in->nsym++] = (Symbol){(token), (vtype), n, in->lineno, in->sp - in->basemrk} + +/* for parse stack */ +#define PUSH_TERMINAL(stack, sym) do { \ + Symbol it = (sym); \ + push((stack), it); \ + if (it.token == T_ERROR) goto err; \ + } while (0) + +#define PUSH_TERMINAL_EXT(cxt, stack, sym) do { \ + Symbol it = (sym); \ + push((stack), it); \ + if (it.token == T_ERROR) goto err; \ + else if (it.token == '(') (cxt) = (stack)->idx_top - 1; \ + else if (it.token == ')') (stack)->items[(cxt)].n = (stack)->idx_top - (cxt) - 1; \ + } while (0) + +/* test for one in a set of 1 to 4 e.g. {t0, t1, t2, t3} */ +#define LOOKAHEAD(x, ...) _EXPAND(GET_MACRO(__VA_ARGS__, _LOOKAHEAD4, _LOOKAHEAD3, _LOOKAHEAD2, _LOOKAHEAD1)(x, __VA_ARGS__)) +#define _LOOKAHEAD1(x, t0) ((t0) == (x).token) +#define _LOOKAHEAD2(x, t0, t1) ((t0) == (x).token || (t1) == (x).token) +#define _LOOKAHEAD3(x, t0, t1, t2) (_LOOKAHEAD2(x, t0, t1) || (t2) == (x).token) +#define _LOOKAHEAD4(x, t0, t1, t2, t3) (_LOOKAHEAD2(x, t0, t1) || _LOOKAHEAD2(x, t2, t3)) + + + + + +/* lexeme */ +typedef struct { + uint8_t token; + union { + uint8_t vtype; + uint8_t errtoken; + }; + uint16_t n; + uint32_t lineno; + union { + ptrdiff_t offset; /* from basemrk */ + void *data; /* production allocation if applicable */ + }; +} Symbol; + +typedef struct SimpleRecord_ { + Symbol *kw; /* 'KEYWORD' */ + Symbol *args;/* '(' */ +} SimpleRecord; + +typedef struct SimpleRecord_ HeaderEntity; + +typedef struct { + Symbol *eid; /* '#' */ + Symbol *eq; /* '=' */ + Symbol *kw; /* 'KEYWORD' */ + Symbol *args;/* '(' */ +} SimpleEntity; + +typedef struct { + Symbol *eid; /* '#' */ + Symbol *eq; /* '=' */ + Symbol *subsupers;/* '(' */ +} ComplexEntity; + + +typedef struct { + FILE *file; + size_t bufsz; + unsigned char *cur, *mrk, *ctxmrk, *lim; + unsigned char *sp, *basemrk; + int eof; + uint32_t lineno; + int nsym; + Symbol sym[3]; + unsigned char *buf; +} Input; + +typedef struct { + int idx_top; + int idx_lim; + Symbol *items; +} Stack; + +/* LL(3) parser */ +typedef struct { + bool error; + bool hold; + Input *in; + Stack *stack; +} P21Parser; + +typedef void (p21_action_cb_t) (P21Parser *, int, void *); +typedef void (p21_error_cb_t) (P21Parser *, int, uint8_t); +typedef void (p21_ud_cb_t) (void *); + +typedef struct { + void *userdata; + p21_error_cb_t *error_cb; + p21_ud_cb_t *ud_init_cb; + p21_ud_cb_t *ud_exit_cb; + p21_action_cb_t *exchange_file_cb; + p21_action_cb_t *header_start_cb; + p21_action_cb_t *header_entity_list_cb; + p21_action_cb_t *data_section_list_cb; + p21_action_cb_t *data_start_cb; + p21_action_cb_t *header_entity_cb; + p21_action_cb_t *simple_entity_instance_cb; + p21_action_cb_t *complex_entity_instance_cb; + p21_action_cb_t *parameter_list_cb; + p21_action_cb_t *parameter_cb; + p21_action_cb_t *entity_instance_list_cb; + p21_action_cb_t *entity_instance_cb; + p21_action_cb_t *simple_record_list_cb; + p21_action_cb_t *simple_record_cb; +} P21ParserActions; + + +void report_error(P21Parser *, const char *); +void _recover(Input *, uint8_t, uint8_t, uint8_t); +Symbol lpop(Input *, uint8_t); + +void p21_parse(P21Parser *, P21ParserActions *); +void p21_exchange_file(P21Parser *, P21ParserActions *); +void p21_header_section(P21Parser *, P21ParserActions *); +void p21_header_entity_list(P21Parser *, P21ParserActions *); +void p21_header_entity(P21Parser *, P21ParserActions *); +void p21_data_section_list(P21Parser *, P21ParserActions *); +void p21_data_section(P21Parser *, P21ParserActions *); +void p21_entity_instance(P21Parser *, P21ParserActions *); +void p21_simple_entity_instance(P21Parser *, P21ParserActions *); +void p21_complex_entity_instance(P21Parser *, P21ParserActions *); +void p21_entity_instance_list(P21Parser *, P21ParserActions *); +void p21_parameter(P21Parser *, P21ParserActions *); +void p21_parameter_list(P21Parser *, P21ParserActions *); +void p21_simple_record(P21Parser *, P21ParserActions *); +void p21_simple_record_list(P21Parser *, P21ParserActions *); + + +void push(Stack *stack, Symbol it) { + if (stack->idx_top == stack->idx_lim) { + Symbol *nitems = realloc(stack->items, 2 * stack->idx_lim * sizeof stack->items[0]); + if (!nitems) { + fprintf(stderr, "failed to grow parser stack, memory exhausted\n"); + exit(1); + } + stack->items = nitems; + stack->idx_lim *= 2; + } + + stack->items[stack->idx_top++] = it; +} + +/* mock implementations */ +void drop(Stack *stack, uint32_t n) { + assert(stack->idx_top >= n); + stack->idx_top -= n; +} + +void unwind(Stack *stack, int bsp) { + stack->idx_top = bsp; +} + +Symbol *pop(Stack *stack) { + assert(stack->idx_top >= 1); + stack->idx_top--; + return stack->items + stack->idx_top; +} + +Symbol *peek(Stack *stack) { + assert(stack->idx_top >= 1); + return stack->items + stack->idx_top - 1; +} + +Symbol lpop(Input *in, uint8_t token) { + Symbol *stack = in->sym; + Symbol sym = stack[0]; + + /* missing input or unexpected lookahead token */ + if (in->nsym == 0) + return (Symbol){T_ERROR, token, 0, in->lineno}; + else if (sym.token != token) + return (Symbol){T_ERROR, token, 0, sym.lineno}; + + if (!--in->nsym) { + memset(&in->sym[0], 0, sizeof in->sym[0]); + } else { + memmove(&in->sym[0], &in->sym[1], in->nsym * sizeof in->sym[0]); + memset(&in->sym[in->nsym], 0, sizeof in->sym[0]); + } + + return sym; +} + +static int fill(Input *in, size_t need) +{ + size_t free; + unsigned char *newbuf; + + if (in->eof) { + return 1; + } + free = in->basemrk - in->buf; + if (free < need) { + newbuf = realloc(in->buf, 2 * in->bufsz + YYMAXFILL); + if (!newbuf) { + fprintf(stderr, "fatal - buffer memory exhausted, exiting\n"); + return 2; + } + in->bufsz *= 2; + in->lim = newbuf + (in->lim - in->buf); + in->cur = newbuf + (in->cur - in->buf); + in->mrk = newbuf + (in->mrk - in->buf); + in->ctxmrk = newbuf + (in->ctxmrk - in->buf); + in->basemrk = newbuf + (in->basemrk - in->buf); + in->sp = newbuf + (in->sp - in->buf); + in->buf = newbuf; + + /* don't memmove() here! */ + free = (in->buf + in->bufsz) - in->lim; + } else { + memmove(in->buf, in->basemrk, in->lim - in->basemrk); + in->lim -= free; + in->cur -= free; + in->mrk -= free; + in->ctxmrk -= free; + in->basemrk -= free; + in->sp -= free; + } + + in->lim += fread(in->lim, 1, free, in->file); + if (in->lim < in->buf + in->bufsz) { + in->eof = 1; + memset(in->lim, 0, YYMAXFILL); + in->lim += YYMAXFILL; + } + return 0; +} + +static void p21_init(P21Parser *p, FILE *file) +{ + Stack *stack; + Input *in; + + in = malloc(sizeof *in); + if (!in) + goto err; + memset(in, 0, sizeof *in); + in->bufsz = INIT_BUF_SZ; + in->buf = malloc(INIT_BUF_SZ + YYMAXFILL); + if (!in->buf) + goto err; + in->file = file; + in->cur = in->basemrk = in->sp = in->lim = in->buf + INIT_BUF_SZ; + in->lineno = 1; + fill(in, 1); + + stack = malloc(sizeof *stack); + if (!stack) + goto err; + memset(stack, 0, sizeof *stack); + stack->idx_lim = 16; + stack->idx_top = 0; + stack->items = malloc(stack->idx_lim * sizeof stack->items[0]); + if (!stack->items) + goto err; + + p->in = in; + p->stack = stack; + p->error = false; + + return; + +err: + fprintf(stderr, "failed to initialise parser\n"); + exit(1); +} + +/* noop error handler */ +void default_error_handler(P21Parser *p, int bsp, uint8_t t) { + Symbol *sym = peek(p->stack); + if (sym->token == T_ERROR) + pop(p->stack); + push(p->stack, (Symbol){t}); +} + +/* TODO: this needs to be reworked */ +void report_error(P21Parser *p, const char *cxt) { + Input *in = p->in; + Symbol *it = peek(p->stack); + int lineno; + unsigned char *cur; + + fprintf(stderr, cxt); + + if (it->token == T_ERROR) { + fprintf(stderr, " syntax error - line: %d\n", it->lineno); + fprintf(stderr, " expected '%c' (token type) ", it->errtoken); + } else { + cur = in->cur; + lineno = in->lineno; + while (1) { + if (*(cur - 2) == '\r' && *(cur - 1) == '\n') { cur -= 2; --lineno; } + else if (*(cur - 1) == '\n') { --cur; --lineno; } + else { break; } + } + fprintf(stderr, " syntax error - line: %d\n", lineno); + } + + if (!in->nsym) { + cur = in->cur; + lineno = in->lineno; + while (1) { + if (*cur == '\r' && *(cur + 1) == '\n') { cur -= 2; --lineno; } + else if (*cur == '\n') { --cur; --lineno; } + else { break; } + } + fprintf(stderr, " unexpected character '%c' (line: %d)\n", *cur, lineno); + } else { + fprintf(stderr, " got '%c' (token type)\n", in->sym[0].token); + } +} + + +void lex_comment(Input *in) { + size_t n; + int comment_lvl = 1; + + while (1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= '*') { + if (yych <= '\r') { + if (yych == '\n') goto yy4; + if (yych >= '\r') goto yy6; + } else { + if (yych <= 0x001F) goto yy2; + if (yych <= ' ') goto yy7; + if (yych <= ')') goto yy10; + goto yy13; + } + } else { + if (yych <= '[') { + if (yych == '/') goto yy16; + if (yych <= 'Z') goto yy10; + } else { + if (yych == ']') goto yy2; + if (yych <= '~') goto yy10; + } + } +yy2: + ++YYCURSOR; +yy3: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy4: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy6: + yych = *++YYCURSOR; + if (yych == '\n') goto yy4; + goto yy3; +yy7: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') { + if (yych <= ')') { + if (yych <= 0x001F) goto yy9; + if (yych <= ' ') goto yy7; + goto yy10; + } else { + if (yych <= '*') goto yy9; + if (yych <= '.') goto yy10; + } + } else { + if (yych <= '\\') { + if (yych != '[') goto yy10; + } else { + if (yych <= ']') goto yy9; + if (yych <= '~') goto yy10; + } + } +yy9: + { n = in->cur - in->sp; } + { continue; } +yy10: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') { + if (yych <= ')') { + if (yych >= ' ') goto yy10; + } else { + if (yych <= '*') goto yy12; + if (yych <= '.') goto yy10; + } + } else { + if (yych <= '\\') { + if (yych != '[') goto yy10; + } else { + if (yych <= ']') goto yy12; + if (yych <= '~') goto yy10; + } + } +yy12: + { n = in->cur - in->sp; } + { continue; } +yy13: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '*') goto yy13; + if (yych == '/') goto yy18; + { n = in->cur - in->sp; } + { continue; } +yy16: + yych = *++YYCURSOR; + if (yych == '*') goto yy20; + { n = in->cur - in->sp; } + { continue; } +yy18: + ++YYCURSOR; + { n = in->cur - in->sp; } + { + if (!--comment_lvl) { break; } + else { continue; } + } +yy20: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + + return; + +err: + fprintf(stderr, "invalid character in comment, exiting\n"); + exit(1); +} + +#define recover(in, ...) GET_MACRO(__VA_ARGS__, _4, _RECOVER3, _RECOVER2, _RECOVER1)(in, __VA_ARGS__) +#define _RECOVER1(in, u0) _recover((in), (u0), 0U, 0U) +#define _RECOVER2(in, u0, u1) _recover((in), (u0), (u1), 0U) +#define _RECOVER3(in, u0, u1, u2) _recover((in), (u0), (u1), (u2)) + +void _recover(Input *in, uint8_t u0, uint8_t u1, uint8_t u2) { + size_t n; + Symbol sym; + + while (in->nsym) { + if (LOOKAHEAD(in->sym[0], u0, u1, u2, T_EOF)) + break; + --in->nsym; + memmove(&in->sym[0], &in->sym[1], in->nsym * sizeof in->sym[0]); + memset(&in->sym[in->nsym], 0, sizeof in->sym[0]); + } + + if (in->nsym) + return; + + while (1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + if ((YYLIMIT - YYCURSOR) < 17) YYFILL(17); + yych = *YYCURSOR; + if (yych <= '-') { + if (yych <= '"') { + if (yych <= '\r') { + if (yych == '\n') goto yy26; + if (yych >= '\r') goto yy28; + } else { + if (yych <= 0x001F) goto yy24; + if (yych <= ' ') goto yy29; + if (yych <= '!') goto yy32; + goto yy33; + } + } else { + if (yych <= '\'') { + if (yych <= '#') goto yy34; + if (yych <= '$') goto yy35; + if (yych >= '\'') goto yy37; + } else { + if (yych <= '*') { + if (yych <= ')') goto yy38; + goto yy40; + } else { + if (yych != ',') goto yy42; + } + } + } + } else { + if (yych <= 'E') { + if (yych <= ':') { + if (yych <= '.') goto yy43; + if (yych <= '/') goto yy44; + if (yych <= '9') goto yy45; + } else { + if (yych <= '@') { + if (yych <= ';') goto yy38; + } else { + if (yych <= 'C') goto yy48; + if (yych <= 'D') goto yy51; + goto yy52; + } + } + } else { + if (yych <= 'Z') { + if (yych <= 'G') goto yy48; + if (yych <= 'H') goto yy53; + if (yych <= 'I') goto yy54; + goto yy48; + } else { + if (yych <= '_') { + if (yych >= '_') goto yy48; + } else { + if (yych <= '`') goto yy24; + if (yych <= 'z') goto yy48; + } + } + } + } +yy24: + ++YYCURSOR; +yy25: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy26: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy28: + yych = *++YYCURSOR; + if (yych == '\n') goto yy26; + goto yy25; +yy29: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy29; + { n = in->cur - in->sp; } + { continue; } +yy32: + yych = *++YYCURSOR; + if (yych <= '^') { + if (yych <= '@') goto yy25; + if (yych <= 'Z') goto yy48; + goto yy25; + } else { + if (yych == '`') goto yy25; + if (yych <= 'z') goto yy48; + goto yy25; + } +yy33: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy25; + if (yych <= '3') goto yy55; + goto yy25; +yy34: + yych = *++YYCURSOR; + if (yych <= '/') goto yy25; + if (yych <= '9') goto yy58; + goto yy25; +yy35: + ++YYCURSOR; + { n = in->cur - in->sp; } + { sym = (Symbol){T_VARIANT, V_EMPTY}; goto check; } +yy37: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '[') { + if (yych <= 0x001F) goto yy25; + if (yych <= 'Z') goto yy62; + goto yy25; + } else { + if (yych == ']') goto yy25; + if (yych <= '~') goto yy62; + goto yy25; + } +yy38: + ++YYCURSOR; + { n = in->cur - in->sp; } + { sym = (Symbol){*in->sp}; goto check; } +yy40: + ++YYCURSOR; + { n = in->cur - in->sp; } + { sym = (Symbol){T_VARIANT, V_DERIVED}; goto check; } +yy42: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= ',') { + if (yych == '+') goto yy66; + goto yy25; + } else { + if (yych <= '-') goto yy66; + if (yych <= '/') goto yy25; + if (yych <= '9') goto yy45; + goto yy25; + } +yy43: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '@') goto yy25; + if (yych <= 'Z') goto yy68; + if (yych == '_') goto yy68; + goto yy25; +yy44: + yych = *++YYCURSOR; + if (yych == '*') goto yy70; + goto yy25; +yy45: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '.') goto yy72; + if (yych <= '/') goto yy47; + if (yych <= '9') goto yy45; +yy47: + { n = in->cur - in->sp; } + { sym = (Symbol){T_VARIANT, V_INTEGER}; goto check; } +yy48: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy49: + if (yych <= 'Z') { + if (yych <= '/') goto yy50; + if (yych <= '9') goto yy48; + if (yych >= 'A') goto yy48; + } else { + if (yych <= '_') { + if (yych >= '_') goto yy48; + } else { + if (yych <= '`') goto yy50; + if (yych <= 'z') goto yy48; + } + } +yy50: + { n = in->cur - in->sp; } + { sym = (Symbol){T_KEYWORD}; goto check; } +yy51: + yych = *++YYCURSOR; + if (yych == 'A') goto yy75; + goto yy49; +yy52: + yych = *++YYCURSOR; + if (yych == 'N') goto yy76; + goto yy49; +yy53: + yych = *++YYCURSOR; + if (yych == 'E') goto yy77; + goto yy49; +yy54: + yych = *++YYCURSOR; + if (yych == 'S') goto yy78; + goto yy49; +yy55: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') { + if (yych == '"') goto yy79; + } else { + if (yych <= '9') goto yy55; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy55; + } +yy57: + YYCURSOR = YYMARKER; + if (yyaccept <= 1) { + if (yyaccept == 0) { + goto yy25; + } else { + goto yy64; + } + } else { + if (yyaccept == 2) { + goto yy74; + } else { + goto yy50; + } + } +yy58: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy60; + if (yych <= '9') goto yy58; +yy60: + { n = in->cur - in->sp; } + { sym = (Symbol){T_EID}; goto check; } +yy61: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy62: + if (yych <= 'Z') { + if (yych <= 0x001F) goto yy57; + if (yych != '\'') goto yy61; + } else { + if (yych <= '\\') { + if (yych <= '[') goto yy57; + goto yy65; + } else { + if (yych <= ']') goto yy57; + if (yych <= '~') goto yy61; + goto yy57; + } + } + yyaccept = 1; + YYMARKER = ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\'') goto yy61; +yy64: + { n = in->cur - in->sp; } + { sym = (Symbol){T_VARIANT, V_STRING}; goto check; } +yy65: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= 'S') { + if (yych <= '@') goto yy57; + if (yych <= 'I') goto yy81; + if (yych <= 'R') goto yy57; + goto yy82; + } else { + if (yych <= 'X') { + if (yych <= 'W') goto yy57; + goto yy83; + } else { + if (yych == '\\') goto yy61; + goto yy57; + } + } +yy66: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= ',') { + if (yych == '+') goto yy66; + goto yy57; + } else { + if (yych <= '-') goto yy66; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy45; + goto yy57; + } +yy68: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '9') { + if (yych == '.') goto yy84; + if (yych <= '/') goto yy57; + goto yy68; + } else { + if (yych <= 'Z') { + if (yych <= '@') goto yy57; + goto yy68; + } else { + if (yych == '_') goto yy68; + goto yy57; + } + } +yy70: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yy72: + yyaccept = 2; + YYMARKER = ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy74; + if (yych <= '9') goto yy72; + if (yych == 'E') goto yy86; +yy74: + { n = in->cur - in->sp; } + { sym = (Symbol){T_VARIANT, V_REAL}; goto check; } +yy75: + yych = *++YYCURSOR; + if (yych == 'T') goto yy88; + goto yy49; +yy76: + yych = *++YYCURSOR; + if (yych == 'D') goto yy89; + goto yy49; +yy77: + yych = *++YYCURSOR; + if (yych == 'A') goto yy90; + goto yy49; +yy78: + yych = *++YYCURSOR; + if (yych == 'O') goto yy91; + goto yy49; +yy79: + ++YYCURSOR; + { n = in->cur - in->sp; } + { sym = (Symbol){T_VARIANT, V_BINARY}; goto check; } +yy81: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yy61; + goto yy57; +yy82: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yy92; + goto yy57; +yy83: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '3') { + if (yych == '2') goto yy93; + goto yy57; + } else { + if (yych <= '4') goto yy94; + if (yych == '\\') goto yy95; + goto yy57; + } +yy84: + ++YYCURSOR; + { n = in->cur - in->sp; } + { sym = (Symbol){T_VARIANT, V_ENUMERATION}; goto check; } +yy86: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= ',') { + if (yych == '+') goto yy86; + goto yy57; + } else { + if (yych <= '-') goto yy86; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy96; + goto yy57; + } +yy88: + yych = *++YYCURSOR; + if (yych == 'A') goto yy98; + goto yy49; +yy89: + yyaccept = 3; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == '-') goto yy99; + if (yych == 'S') goto yy100; + goto yy49; +yy90: + yych = *++YYCURSOR; + if (yych == 'D') goto yy101; + goto yy49; +yy91: + yyaccept = 3; + yych = *(YYMARKER = ++YYCURSOR); + if (yych == '-') goto yy102; + goto yy49; +yy92: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '[') { + if (yych <= 0x001F) goto yy57; + if (yych <= 'Z') goto yy61; + goto yy57; + } else { + if (yych == ']') goto yy57; + if (yych <= '~') goto yy61; + goto yy57; + } +yy93: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yy103; + goto yy57; +yy94: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yy104; + goto yy57; +yy95: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy105; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy105; + goto yy57; +yy96: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy74; + if (yych <= '9') goto yy96; + goto yy74; +yy98: + yych = *++YYCURSOR; + if (yych <= ')') { + if (yych == ' ') goto yy106; + if (yych <= '\'') goto yy49; + goto yy106; + } else { + if (yych <= '/') { + if (yych <= '.') goto yy49; + goto yy106; + } else { + if (yych == ';') goto yy106; + goto yy49; + } + } +yy99: + yych = *++YYCURSOR; + if (yych == 'I') goto yy108; + goto yy57; +yy100: + yych = *++YYCURSOR; + if (yych == 'E') goto yy109; + goto yy49; +yy101: + yych = *++YYCURSOR; + if (yych == 'E') goto yy110; + goto yy49; +yy102: + yych = *++YYCURSOR; + if (yych == '1') goto yy111; + goto yy57; +yy103: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy112; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy112; + goto yy57; +yy104: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy113; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy113; + goto yy57; +yy105: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy61; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy61; + goto yy57; +yy106: + ++YYCURSOR; + YYCURSOR -= 1; + { n = in->cur - in->sp; } + { sym = (Symbol){T_DATA}; goto check; } +yy108: + yych = *++YYCURSOR; + if (yych == 'S') goto yy114; + goto yy57; +yy109: + yych = *++YYCURSOR; + if (yych == 'C') goto yy115; + goto yy49; +yy110: + yych = *++YYCURSOR; + if (yych == 'R') goto yy116; + goto yy49; +yy111: + yych = *++YYCURSOR; + if (yych == '0') goto yy117; + goto yy57; +yy112: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy118; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy118; + goto yy57; +yy113: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy119; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy119; + goto yy57; +yy114: + yych = *++YYCURSOR; + if (yych == 'O') goto yy120; + goto yy57; +yy115: + yych = *++YYCURSOR; + if (yych == ';') goto yy121; + goto yy49; +yy116: + yych = *++YYCURSOR; + if (yych == ';') goto yy123; + goto yy49; +yy117: + yych = *++YYCURSOR; + if (yych == '3') goto yy125; + goto yy57; +yy118: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy126; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy126; + goto yy57; +yy119: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy127; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy127; + goto yy57; +yy120: + yych = *++YYCURSOR; + if (yych == '-') goto yy128; + goto yy57; +yy121: + ++YYCURSOR; + { n = in->cur - in->sp; } + { sym = (Symbol){T_ENDSEC}; goto check; } +yy123: + ++YYCURSOR; + { n = in->cur - in->sp; } + { sym = (Symbol){T_HEADER}; goto check; } +yy125: + yych = *++YYCURSOR; + if (yych == '0') goto yy129; + goto yy57; +yy126: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy130; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy130; + goto yy57; +yy127: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy131; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy131; + goto yy57; +yy128: + yych = *++YYCURSOR; + if (yych == '1') goto yy132; + goto yy57; +yy129: + yych = *++YYCURSOR; + if (yych == '3') goto yy133; + goto yy57; +yy130: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy112; + goto yy57; + } else { + if (yych <= 'F') goto yy112; + if (yych == '\\') goto yy134; + goto yy57; + } +yy131: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy135; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy135; + goto yy57; +yy132: + yych = *++YYCURSOR; + if (yych == '0') goto yy136; + goto yy57; +yy133: + yych = *++YYCURSOR; + if (yych == '-') goto yy137; + goto yy57; +yy134: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == 'X') goto yy138; + goto yy57; +yy135: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy139; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy139; + goto yy57; +yy136: + yych = *++YYCURSOR; + if (yych == '3') goto yy140; + goto yy57; +yy137: + yych = *++YYCURSOR; + if (yych == '2') goto yy141; + goto yy57; +yy138: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '0') goto yy81; + goto yy57; +yy139: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy142; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy142; + goto yy57; +yy140: + yych = *++YYCURSOR; + if (yych == '0') goto yy143; + goto yy57; +yy141: + yych = *++YYCURSOR; + if (yych == '1') goto yy144; + goto yy57; +yy142: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy145; + if (yych <= '@') goto yy57; + if (yych <= 'F') goto yy145; + goto yy57; +yy143: + yych = *++YYCURSOR; + if (yych == '3') goto yy146; + goto yy57; +yy144: + yych = *++YYCURSOR; + if (yych == ';') goto yy147; + goto yy57; +yy145: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yy57; + if (yych <= '9') goto yy113; + goto yy57; + } else { + if (yych <= 'F') goto yy113; + if (yych == '\\') goto yy134; + goto yy57; + } +yy146: + yych = *++YYCURSOR; + if (yych == '-') goto yy149; + goto yy57; +yy147: + ++YYCURSOR; + { n = in->cur - in->sp; } + { sym = (Symbol){T_P21_START}; goto check; } +yy149: + yych = *++YYCURSOR; + if (yych != '2') goto yy57; + yych = *++YYCURSOR; + if (yych != '1') goto yy57; + yych = *++YYCURSOR; + if (yych != ';') goto yy57; + ++YYCURSOR; + { n = in->cur - in->sp; } + { sym = (Symbol){T_P21_END}; goto check; } +} + +check: + if (LOOKAHEAD(sym, u0, u1, u2, T_EOF)) { + PUSH_SYMBOL(sym.token, sym.vtype); + break; + } + } + + return; + +err: + fprintf(stderr, "fatal, failed to resolve follow set (%c, %c, %c)\n", u0, u1, u2); + exit(1); +} + + +/* + * P21Parser + */ +void p21_parse(P21Parser *p, P21ParserActions *act) { + if (act->ud_init_cb) + act->ud_init_cb(act->userdata); + + p21_exchange_file(p, act); + + if (act->ud_exit_cb) + act->ud_exit_cb(act->userdata); + + assert(p->stack->idx_top == 1); + return; + +err: + report_error(p, "exchange_file' << 0 >>\n"); +} + +void p21_exchange_file(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 13) YYFILL(13); + yych = *YYCURSOR; + if (yych <= 0x001F) { + if (yych <= '\n') { + if (yych >= '\n') goto yy158; + } else { + if (yych == '\r') goto yy160; + } + } else { + if (yych <= '/') { + if (yych <= ' ') goto yy161; + if (yych >= '/') goto yy164; + } else { + if (yych == 'I') goto yy165; + } + } + ++YYCURSOR; +yy157: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy158: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy160: + yych = *++YYCURSOR; + if (yych == '\n') goto yy158; + goto yy157; +yy161: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy161; + { n = in->cur - in->sp; } + { continue; } +yy164: + yych = *++YYCURSOR; + if (yych == '*') goto yy166; + goto yy157; +yy165: + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'S') goto yy168; + goto yy157; +yy166: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yy168: + yych = *++YYCURSOR; + if (yych == 'O') goto yy170; +yy169: + YYCURSOR = YYMARKER; + goto yy157; +yy170: + yych = *++YYCURSOR; + if (yych != '-') goto yy169; + yych = *++YYCURSOR; + if (yych != '1') goto yy169; + yych = *++YYCURSOR; + if (yych != '0') goto yy169; + yych = *++YYCURSOR; + if (yych != '3') goto yy169; + yych = *++YYCURSOR; + if (yych != '0') goto yy169; + yych = *++YYCURSOR; + if (yych != '3') goto yy169; + yych = *++YYCURSOR; + if (yych != '-') goto yy169; + yych = *++YYCURSOR; + if (yych != '2') goto yy169; + yych = *++YYCURSOR; + if (yych != '1') goto yy169; + yych = *++YYCURSOR; + if (yych != ';') goto yy169; + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_P21_START); continue;} +} + + } + PUSH_TERMINAL(p->stack, lpop(in, T_P21_START)); + + p21_header_section(p, act); + p21_data_section_list(p, act); + + PUSH_TERMINAL(p->stack, lpop(in, T_P21_END)); + + if (p->error) + goto err; + + /* user action */ + if (act->exchange_file_cb) + act->exchange_file_cb(p, bsp, act->userdata); + + /* default reduction */ + p->stack->items[bsp] = (Symbol){P_FILE}; + drop(p->stack, p->stack->idx_top - bsp - 1); + + return; + +err: + report_error(p, "exchange_file << 1 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_FILE); + else default_error_handler(p, bsp, P_FILE); + recover(in, T_EOF); +} + +void p21_header_section(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + if (yych <= 0x001F) { + if (yych <= '\n') { + if (yych >= '\n') goto yya186; + } else { + if (yych == '\r') goto yya188; + } + } else { + if (yych <= '/') { + if (yych <= ' ') goto yya189; + if (yych >= '/') goto yya192; + } else { + if (yych == 'H') goto yya193; + } + } + ++YYCURSOR; +yya185: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yya186: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yya188: + yych = *++YYCURSOR; + if (yych == '\n') goto yya186; + goto yya185; +yya189: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yya189; + { n = in->cur - in->sp; } + { continue; } +yya192: + yych = *++YYCURSOR; + if (yych == '*') goto yya194; + goto yya185; +yya193: + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'E') goto yya196; + goto yya185; +yya194: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yya196: + yych = *++YYCURSOR; + if (yych == 'A') goto yya198; +yya197: + YYCURSOR = YYMARKER; + goto yya185; +yya198: + yych = *++YYCURSOR; + if (yych != 'D') goto yya197; + yych = *++YYCURSOR; + if (yych != 'E') goto yya197; + yych = *++YYCURSOR; + if (yych != 'R') goto yya197; + yych = *++YYCURSOR; + if (yych != ';') goto yya197; + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_HEADER); continue; } +} + + } + PUSH_TERMINAL(p->stack, lpop(in, T_HEADER)); + + /* section callback */ + if (act->header_start_cb) + act->header_start_cb(p, bsp, act->userdata); + + /* mandatory headers */ + p21_header_entity(p, act); + p21_header_entity(p, act); + p21_header_entity(p, act); + + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + if (yych <= '/') { + if (yych <= '\r') { + if (yych == '\n') goto yyb208; + if (yych >= '\r') goto yyb210; + } else { + if (yych <= ' ') { + if (yych >= ' ') goto yyb211; + } else { + if (yych <= '!') goto yyb214; + if (yych >= '/') goto yyb215; + } + } + } else { + if (yych <= 'Z') { + if (yych <= '@') goto yyb206; + if (yych == 'E') goto yyb219; + goto yyb216; + } else { + if (yych <= '_') { + if (yych >= '_') goto yyb216; + } else { + if (yych <= '`') goto yyb206; + if (yych <= 'z') goto yyb216; + } + } + } +yyb206: + ++YYCURSOR; +yyb207: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yyb208: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yyb210: + yych = *++YYCURSOR; + if (yych == '\n') goto yyb208; + goto yyb207; +yyb211: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yyb211; + { n = in->cur - in->sp; } + { continue; } +yyb214: + yych = *++YYCURSOR; + if (yych <= '^') { + if (yych <= '@') goto yyb207; + if (yych <= 'Z') goto yyb216; + goto yyb207; + } else { + if (yych == '`') goto yyb207; + if (yych <= 'z') goto yyb216; + goto yyb207; + } +yyb215: + yych = *++YYCURSOR; + if (yych == '*') goto yyb220; + goto yyb207; +yyb216: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yyb217: + if (yych <= 'Z') { + if (yych <= '/') goto yyb218; + if (yych <= '9') goto yyb216; + if (yych >= 'A') goto yyb216; + } else { + if (yych <= '_') { + if (yych >= '_') goto yyb216; + } else { + if (yych <= '`') goto yyb218; + if (yych <= 'z') goto yyb216; + } + } +yyb218: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_KEYWORD); continue; } +yyb219: + yych = *++YYCURSOR; + if (yych == 'N') goto yyb222; + goto yyb217; +yyb220: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yyb222: + yych = *++YYCURSOR; + if (yych != 'D') goto yyb217; + yych = *++YYCURSOR; + if (yych != 'S') goto yyb217; + yych = *++YYCURSOR; + if (yych != 'E') goto yyb217; + yych = *++YYCURSOR; + if (yych != 'C') goto yyb217; + yych = *++YYCURSOR; + if (yych != ';') goto yyb217; + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_ENDSEC); continue; } +} + + } + + /* optional headers */ + if (LOOKAHEAD(in->sym[0], T_KEYWORD)) + p21_header_entity_list(p, act); + + PUSH_TERMINAL(p->stack, lpop(in, T_ENDSEC)); + + if (p->error) + goto err; + + /* default reduction */ + p->stack->items[bsp] = (Symbol){P_HEADERSECTION}; + drop(p->stack, p->stack->idx_top - bsp - 1); + + return; + +err: + report_error(p, "header_section << 2 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_HEADERSECTION); + else default_error_handler(p, bsp, P_HEADERSECTION); + recover(in, T_DATA); +} + +void p21_data_section_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + uint32_t len = 0; + Input *in = p->in; + + do { + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 17) YYFILL(17); + yych = *YYCURSOR; + if (yych <= ' ') { + if (yych <= '\f') { + if (yych == '\n') goto yy233; + } else { + if (yych <= '\r') goto yy235; + if (yych >= ' ') goto yy236; + } + } else { + if (yych <= 'C') { + if (yych == '/') goto yy239; + } else { + if (yych <= 'D') goto yy240; + if (yych <= 'E') goto yy241; + } + } + ++YYCURSOR; +yy232: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy233: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy235: + yych = *++YYCURSOR; + if (yych == '\n') goto yy233; + goto yy232; +yy236: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy236; + { n = in->cur - in->sp; } + { continue; } +yy239: + yych = *++YYCURSOR; + if (yych == '*') goto yy242; + goto yy232; +yy240: + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'A') goto yy244; + goto yy232; +yy241: + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'N') goto yy246; + goto yy232; +yy242: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yy244: + yych = *++YYCURSOR; + if (yych == 'T') goto yy247; +yy245: + YYCURSOR = YYMARKER; + goto yy232; +yy246: + yych = *++YYCURSOR; + if (yych == 'D') goto yy248; + goto yy245; +yy247: + yych = *++YYCURSOR; + if (yych == 'A') goto yy249; + goto yy245; +yy248: + yych = *++YYCURSOR; + if (yych == '-') goto yy250; + goto yy245; +yy249: + yych = *++YYCURSOR; + if (yych <= ')') { + if (yych == ' ') goto yy251; + if (yych <= '\'') goto yy245; + goto yy251; + } else { + if (yych <= '/') { + if (yych <= '.') goto yy245; + goto yy251; + } else { + if (yych == ';') goto yy251; + goto yy245; + } + } +yy250: + yych = *++YYCURSOR; + if (yych == 'I') goto yy253; + goto yy245; +yy251: + ++YYCURSOR; + YYCURSOR -= 1; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_DATA); continue; } +yy253: + yych = *++YYCURSOR; + if (yych != 'S') goto yy245; + yych = *++YYCURSOR; + if (yych != 'O') goto yy245; + yych = *++YYCURSOR; + if (yych != '-') goto yy245; + yych = *++YYCURSOR; + if (yych != '1') goto yy245; + yych = *++YYCURSOR; + if (yych != '0') goto yy245; + yych = *++YYCURSOR; + if (yych != '3') goto yy245; + yych = *++YYCURSOR; + if (yych != '0') goto yy245; + yych = *++YYCURSOR; + if (yych != '3') goto yy245; + yych = *++YYCURSOR; + if (yych != '-') goto yy245; + yych = *++YYCURSOR; + if (yych != '2') goto yy245; + yych = *++YYCURSOR; + if (yych != '1') goto yy245; + yych = *++YYCURSOR; + if (yych != ';') goto yy245; + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_P21_END); continue; } +} + + } + if (!LOOKAHEAD(in->sym[0], T_DATA)) + break; + p21_data_section(p, act); + } while (++len); + + /* one or more */ + if (!len) { + push(p->stack, (Symbol){T_ERROR, T_DATA, 0, in->sym[0].lineno}); + p->error = true; + } + + if(p->error) + goto err; + + /* user action */ + if (act->data_section_list_cb) + act->data_section_list_cb(p, bsp, act->userdata); + + /* default reduction */ + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + + return; + +err: + report_error(p, "data_section_list << 3 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, T_P21_END); +} + +void p21_data_section(P21Parser *p, P21ParserActions *act) { + size_t n, cxt; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 2) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= ' ') { + if (yych <= '\f') { + if (yych == '\n') goto yya271; + } else { + if (yych <= '\r') goto yya273; + if (yych >= ' ') goto yya274; + } + } else { + if (yych <= '.') { + if (yych == '(') goto yya277; + } else { + if (yych <= '/') goto yya279; + if (yych == ';') goto yya277; + } + } + ++YYCURSOR; +yya270: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yya271: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yya273: + yych = *++YYCURSOR; + if (yych == '\n') goto yya271; + goto yya270; +yya274: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yya274; + { n = in->cur - in->sp; } + { continue; } +yya277: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(*in->sp); continue; } +yya279: + yych = *++YYCURSOR; + if (yych != '*') goto yya270; + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + PUSH_TERMINAL(p->stack, lpop(in, T_DATA)); + + if (LOOKAHEAD(in->sym[0], '(')) { + PUSH_TERMINAL(p->stack, lpop(in, '(')); + + p21_parameter_list(p, act); + while (in->nsym < 2) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= 0x001F) { + if (yych <= '\n') { + if (yych >= '\n') goto yyb286; + } else { + if (yych == '\r') goto yyb288; + } + } else { + if (yych <= '/') { + if (yych <= ' ') goto yyb289; + if (yych >= '/') goto yyb292; + } else { + if (yych == ';') goto yyb293; + } + } + ++YYCURSOR; +yyb285: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yyb286: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yyb288: + yych = *++YYCURSOR; + if (yych == '\n') goto yyb286; + goto yyb285; +yyb289: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yyb289; + { n = in->cur - in->sp; } + { continue; } +yyb292: + yych = *++YYCURSOR; + if (yych == '*') goto yyb295; + goto yyb285; +yyb293: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(';'); continue; } +yyb295: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + + PUSH_TERMINAL(p->stack, lpop(in, ')')); + } + PUSH_TERMINAL(p->stack, lpop(in, ';')); + + if (act->data_start_cb) + act->data_start_cb(p, bsp, act->userdata); + + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + if (yych <= ' ') { + if (yych <= '\f') { + if (yych == '\n') goto yyc301; + } else { + if (yych <= '\r') goto yyc303; + if (yych >= ' ') goto yyc304; + } + } else { + if (yych <= '.') { + if (yych == '#') goto yyc307; + } else { + if (yych <= '/') goto yyc308; + if (yych == 'E') goto yyc309; + } + } + ++YYCURSOR; +yyc300: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yyc301: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yyc303: + yych = *++YYCURSOR; + if (yych == '\n') goto yyc301; + goto yyc300; +yyc304: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yyc304; + { n = in->cur - in->sp; } + { continue; } +yyc307: + yych = *++YYCURSOR; + if (yych <= '/') goto yyc300; + if (yych <= '9') goto yyc310; + goto yyc300; +yyc308: + yych = *++YYCURSOR; + if (yych == '*') goto yyc313; + goto yyc300; +yyc309: + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'N') goto yyc315; + goto yyc300; +yyc310: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yyc312; + if (yych <= '9') goto yyc310; +yyc312: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_EID); continue; } +yyc313: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yyc315: + yych = *++YYCURSOR; + if (yych == 'D') goto yyc317; +yyc316: + YYCURSOR = YYMARKER; + goto yyc300; +yyc317: + yych = *++YYCURSOR; + if (yych != 'S') goto yyc316; + yych = *++YYCURSOR; + if (yych != 'E') goto yyc316; + yych = *++YYCURSOR; + if (yych != 'C') goto yyc316; + yych = *++YYCURSOR; + if (yych != ';') goto yyc316; + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_ENDSEC); continue; } +} + + } + if (LOOKAHEAD(in->sym[0], T_EID)) + p21_entity_instance_list(p, act); + + PUSH_TERMINAL(p->stack, lpop(in, T_ENDSEC)); + + if (p->error) + goto err; + + /* default reduction */ + p->stack->items[bsp] = (Symbol){P_DATASECTION}; + drop(p->stack, p->stack->idx_top - bsp - 1); + + return; + +err: + report_error(p, "data_section << 4 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_DATASECTION); + else default_error_handler(p, bsp, P_DATASECTION); + recover(in, T_P21_END, T_DATA); +} + +void p21_header_entity(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + /* set KEYWORD as basemrk to prevent fill() recycling the buffer before user action */ + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= '.') { + if (yych <= '\r') { + if (yych == '\n') goto yy327; + if (yych >= '\r') goto yy329; + } else { + if (yych <= 0x001F) goto yy325; + if (yych <= ' ') goto yy330; + if (yych <= '!') goto yy333; + } + } else { + if (yych <= '^') { + if (yych <= '/') goto yy334; + if (yych <= '@') goto yy325; + if (yych <= 'Z') goto yy335; + } else { + if (yych == '`') goto yy325; + if (yych <= 'z') goto yy335; + } + } +yy325: + ++YYCURSOR; +yy326: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy327: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy329: + yych = *++YYCURSOR; + if (yych == '\n') goto yy327; + goto yy326; +yy330: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy330; + { n = in->cur - in->sp; } + { continue; } +yy333: + yych = *++YYCURSOR; + if (yych <= '^') { + if (yych <= '@') goto yy326; + if (yych <= 'Z') goto yy335; + goto yy326; + } else { + if (yych == '`') goto yy326; + if (yych <= 'z') goto yy335; + goto yy326; + } +yy334: + yych = *++YYCURSOR; + if (yych == '*') goto yy338; + goto yy326; +yy335: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= 'Z') { + if (yych <= '/') goto yy337; + if (yych <= '9') goto yy335; + if (yych >= 'A') goto yy335; + } else { + if (yych <= '_') { + if (yych >= '_') goto yy335; + } else { + if (yych <= '`') goto yy337; + if (yych <= 'z') goto yy335; + } + } +yy337: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_KEYWORD); continue; } +yy338: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + + /* set KEYWORD as basemrk to prevent fill() recycling the buffer before user action */ + assert(in->nsym == 1); + in->basemrk += in->sym[0].offset; + in->sym[0].offset = 0; + + p21_simple_record(p, act); + + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= 0x001F) { + if (yych <= '\n') { + if (yych >= '\n') goto yy344; + } else { + if (yych == '\r') goto yy346; + } + } else { + if (yych <= '/') { + if (yych <= ' ') goto yy347; + if (yych >= '/') goto yy350; + } else { + if (yych == ';') goto yy351; + } + } + ++YYCURSOR; +yy343: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy344: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy346: + yych = *++YYCURSOR; + if (yych == '\n') goto yy344; + goto yy343; +yy347: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy347; + { n = in->cur - in->sp; } + { continue; } +yy350: + yych = *++YYCURSOR; + if (yych == '*') goto yy353; + goto yy343; +yy351: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(';'); continue; } +yy353: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + PUSH_TERMINAL(p->stack, lpop(in, ';')); + + if (p->error) + goto err; + + /* user action */ + if (act->header_entity_cb) + act->header_entity_cb(p, bsp, act->userdata); + + /* reduction */ + assert(!p->hold); + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_HEADERENTITY}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "header_entity << 5 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_HEADERENTITY); + else default_error_handler(p, bsp, P_HEADERENTITY); + recover(in, T_ENDSEC, T_KEYWORD); +} + +void p21_header_entity_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + p21_header_entity(p, act); + + do { + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + if (yych <= '/') { + if (yych <= '\r') { + if (yych == '\n') goto yy359; + if (yych >= '\r') goto yy361; + } else { + if (yych <= ' ') { + if (yych >= ' ') goto yy362; + } else { + if (yych <= '!') goto yy365; + if (yych >= '/') goto yy366; + } + } + } else { + if (yych <= 'Z') { + if (yych <= '@') goto yy357; + if (yych == 'E') goto yy370; + goto yy367; + } else { + if (yych <= '_') { + if (yych >= '_') goto yy367; + } else { + if (yych <= '`') goto yy357; + if (yych <= 'z') goto yy367; + } + } + } +yy357: + ++YYCURSOR; +yy358: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy359: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy361: + yych = *++YYCURSOR; + if (yych == '\n') goto yy359; + goto yy358; +yy362: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy362; + { n = in->cur - in->sp; } + { continue; } +yy365: + yych = *++YYCURSOR; + if (yych <= '^') { + if (yych <= '@') goto yy358; + if (yych <= 'Z') goto yy367; + goto yy358; + } else { + if (yych == '`') goto yy358; + if (yych <= 'z') goto yy367; + goto yy358; + } +yy366: + yych = *++YYCURSOR; + if (yych == '*') goto yy371; + goto yy358; +yy367: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy368: + if (yych <= 'Z') { + if (yych <= '/') goto yy369; + if (yych <= '9') goto yy367; + if (yych >= 'A') goto yy367; + } else { + if (yych <= '_') { + if (yych >= '_') goto yy367; + } else { + if (yych <= '`') goto yy369; + if (yych <= 'z') goto yy367; + } + } +yy369: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_KEYWORD); continue; } +yy370: + yych = *++YYCURSOR; + if (yych == 'N') goto yy373; + goto yy368; +yy371: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yy373: + yych = *++YYCURSOR; + if (yych != 'D') goto yy368; + yych = *++YYCURSOR; + if (yych != 'S') goto yy368; + yych = *++YYCURSOR; + if (yych != 'E') goto yy368; + yych = *++YYCURSOR; + if (yych != 'C') goto yy368; + yych = *++YYCURSOR; + if (yych != ';') goto yy368; + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_ENDSEC); continue; } +} + + } + if (!LOOKAHEAD(in->sym[0], T_KEYWORD)) + break; + p21_header_entity(p, act); + } while (1); + + if (p->error) + goto err; + + + /* user action */ + if (act->header_entity_list_cb) + act->header_entity_list_cb(p, bsp, act->userdata); + + /* reduction */ + assert(!p->hold); + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "header_entity_list << 6 >>"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, T_ENDSEC); +} + +void p21_entity_instance_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + p21_entity_instance(p, act); + + do { + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7); + yych = *YYCURSOR; + if (yych <= ' ') { + if (yych <= '\f') { + if (yych == '\n') goto yy384; + } else { + if (yych <= '\r') goto yy386; + if (yych >= ' ') goto yy387; + } + } else { + if (yych <= '.') { + if (yych == '#') goto yy390; + } else { + if (yych <= '/') goto yy391; + if (yych == 'E') goto yy392; + } + } + ++YYCURSOR; +yy383: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy384: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy386: + yych = *++YYCURSOR; + if (yych == '\n') goto yy384; + goto yy383; +yy387: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy387; + { n = in->cur - in->sp; } + { continue; } +yy390: + yych = *++YYCURSOR; + if (yych <= '/') goto yy383; + if (yych <= '9') goto yy393; + goto yy383; +yy391: + yych = *++YYCURSOR; + if (yych == '*') goto yy396; + goto yy383; +yy392: + yych = *(YYMARKER = ++YYCURSOR); + if (yych == 'N') goto yy398; + goto yy383; +yy393: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy395; + if (yych <= '9') goto yy393; +yy395: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_EID); continue; } +yy396: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yy398: + yych = *++YYCURSOR; + if (yych == 'D') goto yy400; +yy399: + YYCURSOR = YYMARKER; + goto yy383; +yy400: + yych = *++YYCURSOR; + if (yych != 'S') goto yy399; + yych = *++YYCURSOR; + if (yych != 'E') goto yy399; + yych = *++YYCURSOR; + if (yych != 'C') goto yy399; + yych = *++YYCURSOR; + if (yych != ';') goto yy399; + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_ENDSEC); continue; } +} + + } + if (!LOOKAHEAD(in->sym[0], T_EID)) + break; + p21_entity_instance(p, act); + } while (1); + + if (p->error) + goto err; + + /* user action */ + if (act->entity_instance_list_cb) + act->entity_instance_list_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "entity_instance_list << 7 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, T_ENDSEC); +} + +void p21_parameter_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + p21_parameter(p, act); + + do { + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= ' ') { + if (yych <= '\f') { + if (yych == '\n') goto yy410; + } else { + if (yych <= '\r') goto yy412; + if (yych >= ' ') goto yy413; + } + } else { + if (yych <= '+') { + if (yych == ')') goto yy416; + } else { + if (yych <= ',') goto yy416; + if (yych == '/') goto yy418; + } + } + ++YYCURSOR; +yy409: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy410: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy412: + yych = *++YYCURSOR; + if (yych == '\n') goto yy410; + goto yy409; +yy413: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy413; + { n = in->cur - in->sp; } + { continue; } +yy416: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(*in->sp); continue; } +yy418: + yych = *++YYCURSOR; + if (yych != '*') goto yy409; + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + if (LOOKAHEAD(in->sym[0], ')')) + break; + + PUSH_TERMINAL(p->stack, lpop(in, ',')); + p21_parameter(p, act); + } while (1); + + if (p->error) + goto err; + + /* user action */ + if (act->parameter_list_cb) + act->parameter_list_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "parameter_list << 8 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, ')', ';'); +} + +void p21_entity_instance(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + /* set EID as basemrk to prevent fill() recycling the buffer before user action */ + assert(in->nsym == 1); + in->basemrk += in->sym[0].offset; + in->sym[0].offset = 0; + + while (in->nsym < 3) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= '.') { + if (yych <= 0x001F) { + if (yych <= '\n') { + if (yych >= '\n') goto yy425; + } else { + if (yych == '\r') goto yy427; + } + } else { + if (yych <= '!') { + if (yych <= ' ') goto yy428; + goto yy431; + } else { + if (yych == '(') goto yy432; + } + } + } else { + if (yych <= 'Z') { + if (yych <= '<') { + if (yych <= '/') goto yy434; + } else { + if (yych <= '=') goto yy432; + if (yych >= 'A') goto yy435; + } + } else { + if (yych <= '_') { + if (yych >= '_') goto yy435; + } else { + if (yych <= '`') goto yy423; + if (yych <= 'z') goto yy435; + } + } + } +yy423: + ++YYCURSOR; +yy424: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy425: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy427: + yych = *++YYCURSOR; + if (yych == '\n') goto yy425; + goto yy424; +yy428: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy428; + { n = in->cur - in->sp; } + { continue; } +yy431: + yych = *++YYCURSOR; + if (yych <= '^') { + if (yych <= '@') goto yy424; + if (yych <= 'Z') goto yy435; + goto yy424; + } else { + if (yych == '`') goto yy424; + if (yych <= 'z') goto yy435; + goto yy424; + } +yy432: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(*in->sp); continue; } +yy434: + yych = *++YYCURSOR; + if (yych == '*') goto yy438; + goto yy424; +yy435: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= 'Z') { + if (yych <= '/') goto yy437; + if (yych <= '9') goto yy435; + if (yych >= 'A') goto yy435; + } else { + if (yych <= '_') { + if (yych >= '_') goto yy435; + } else { + if (yych <= '`') goto yy437; + if (yych <= 'z') goto yy435; + } + } +yy437: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_KEYWORD); continue; } +yy438: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + if (!LOOKAHEAD(in->sym[0], T_EID) || !LOOKAHEAD(in->sym[1], '=')) + goto err; + + if (LOOKAHEAD(in->sym[2], T_KEYWORD)) { + p21_simple_entity_instance(p, act); + } else if (LOOKAHEAD(in->sym[2], '(')) { + p21_complex_entity_instance(p, act); + } + + if (p->error) + goto err; + + /* user action */ + if (act->entity_instance_cb) + act->entity_instance_cb(p, bsp, act->userdata); + + /* no default reduction */ + + return; + +err: + report_error(p, "entity_instance << 9 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, T_ENDSEC, T_EID); +} + +void p21_simple_entity_instance(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + PUSH_TERMINAL(p->stack, lpop(in, T_EID)); + PUSH_TERMINAL(p->stack, lpop(in, '=')); + + p21_simple_record(p, act); + + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= 0x001F) { + if (yych <= '\n') { + if (yych >= '\n') goto yy444; + } else { + if (yych == '\r') goto yy446; + } + } else { + if (yych <= '/') { + if (yych <= ' ') goto yy447; + if (yych >= '/') goto yy450; + } else { + if (yych == ';') goto yy451; + } + } + ++YYCURSOR; +yy443: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy444: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy446: + yych = *++YYCURSOR; + if (yych == '\n') goto yy444; + goto yy443; +yy447: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy447; + { n = in->cur - in->sp; } + { continue; } +yy450: + yych = *++YYCURSOR; + if (yych == '*') goto yy453; + goto yy443; +yy451: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(';'); continue; } +yy453: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + PUSH_TERMINAL(p->stack, lpop(in, ';')); + + if (p->error) + goto err; + + /* user action */ + if (act->simple_entity_instance_cb) + act->simple_entity_instance_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_SIMPLEENTITY}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "simple_entity_instance << 10 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_SIMPLEENTITY); + else default_error_handler(p, bsp, P_SIMPLEENTITY); + recover(in, T_ENDSEC, T_EID); +} + + +void p21_complex_entity_instance(P21Parser *p, P21ParserActions *act) { + size_t n, c; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + PUSH_TERMINAL(p->stack, lpop(in, T_EID)); + PUSH_TERMINAL(p->stack, lpop(in, '=')); + PUSH_TERMINAL_EXT(c, p->stack, lpop(in, '(')); + + p21_simple_record_list(p, act); + + while (in->nsym < 2) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= 0x001F) { + if (yych <= '\n') { + if (yych >= '\n') goto yy459; + } else { + if (yych == '\r') goto yy461; + } + } else { + if (yych <= '/') { + if (yych <= ' ') goto yy462; + if (yych >= '/') goto yy465; + } else { + if (yych == ';') goto yy466; + } + } + ++YYCURSOR; +yy458: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy459: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy461: + yych = *++YYCURSOR; + if (yych == '\n') goto yy459; + goto yy458; +yy462: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy462; + { n = in->cur - in->sp; } + { continue; } +yy465: + yych = *++YYCURSOR; + if (yych == '*') goto yy468; + goto yy458; +yy466: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(';'); continue; } +yy468: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + + PUSH_TERMINAL_EXT(c, p->stack, lpop(in, ')')); + PUSH_TERMINAL(p->stack, lpop(in, ';')); + + if (p->error) + goto err; + + /* user action */ + if (act->complex_entity_instance_cb) + act->complex_entity_instance_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_COMPLEXENTITY}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "complex_entity_instance << 11 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_COMPLEXENTITY); + else default_error_handler(p, bsp, P_COMPLEXENTITY); + recover(in, T_ENDSEC, T_EID); +} + +void p21_simple_record(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 3) { + in->sp = in->cur; + +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= ')') { + if (yych <= ' ') { + if (yych <= '\f') { + if (yych == '\n') goto yy474; + } else { + if (yych <= '\r') goto yy476; + if (yych >= ' ') goto yy477; + } + } else { + if (yych <= '#') { + if (yych <= '!') goto yy480; + if (yych <= '"') goto yy481; + goto yy482; + } else { + if (yych <= '$') goto yy483; + if (yych <= '&') goto yy472; + if (yych <= '\'') goto yy485; + goto yy486; + } + } + } else { + if (yych <= '9') { + if (yych <= ',') { + if (yych <= '*') goto yy488; + if (yych <= '+') goto yy490; + } else { + if (yych <= '-') goto yy490; + if (yych <= '.') goto yy491; + if (yych <= '/') goto yy492; + goto yy493; + } + } else { + if (yych <= '^') { + if (yych <= '@') goto yy472; + if (yych <= 'Z') goto yy496; + } else { + if (yych == '`') goto yy472; + if (yych <= 'z') goto yy496; + } + } + } +yy472: + ++YYCURSOR; +yy473: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy474: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy476: + yych = *++YYCURSOR; + if (yych == '\n') goto yy474; + goto yy473; +yy477: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy477; + { n = in->cur - in->sp; } + { continue; } +yy480: + yych = *++YYCURSOR; + if (yych <= '^') { + if (yych <= '@') goto yy473; + if (yych <= 'Z') goto yy496; + goto yy473; + } else { + if (yych == '`') goto yy473; + if (yych <= 'z') goto yy496; + goto yy473; + } +yy481: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yy473; + if (yych <= '3') goto yy499; + goto yy473; +yy482: + yych = *++YYCURSOR; + if (yych <= '/') goto yy473; + if (yych <= '9') goto yy502; + goto yy473; +yy483: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_EMPTY); continue; } +yy485: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '[') { + if (yych <= 0x001F) goto yy473; + if (yych <= 'Z') goto yy506; + goto yy473; + } else { + if (yych == ']') goto yy473; + if (yych <= '~') goto yy506; + goto yy473; + } +yy486: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(*in->sp); continue; } +yy488: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_DERIVED); continue; } +yy490: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= ',') { + if (yych == '+') goto yy510; + goto yy473; + } else { + if (yych <= '-') goto yy510; + if (yych <= '/') goto yy473; + if (yych <= '9') goto yy493; + goto yy473; + } +yy491: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '@') goto yy473; + if (yych <= 'Z') goto yy512; + if (yych == '_') goto yy512; + goto yy473; +yy492: + yych = *++YYCURSOR; + if (yych == '*') goto yy514; + goto yy473; +yy493: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '.') goto yy516; + if (yych <= '/') goto yy495; + if (yych <= '9') goto yy493; +yy495: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_INTEGER); continue; } +yy496: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= 'Z') { + if (yych <= '/') goto yy498; + if (yych <= '9') goto yy496; + if (yych >= 'A') goto yy496; + } else { + if (yych <= '_') { + if (yych >= '_') goto yy496; + } else { + if (yych <= '`') goto yy498; + if (yych <= 'z') goto yy496; + } + } +yy498: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_KEYWORD); continue; } +yy499: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') { + if (yych == '"') goto yy519; + } else { + if (yych <= '9') goto yy499; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy499; + } +yy501: + YYCURSOR = YYMARKER; + if (yyaccept <= 1) { + if (yyaccept == 0) { + goto yy473; + } else { + goto yy508; + } + } else { + goto yy518; + } +yy502: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy504; + if (yych <= '9') goto yy502; +yy504: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_EID); continue; } +yy505: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy506: + if (yych <= 'Z') { + if (yych <= 0x001F) goto yy501; + if (yych != '\'') goto yy505; + } else { + if (yych <= '\\') { + if (yych <= '[') goto yy501; + goto yy509; + } else { + if (yych <= ']') goto yy501; + if (yych <= '~') goto yy505; + goto yy501; + } + } + yyaccept = 1; + YYMARKER = ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\'') goto yy505; +yy508: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_STRING); continue; } +yy509: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= 'S') { + if (yych <= '@') goto yy501; + if (yych <= 'I') goto yy521; + if (yych <= 'R') goto yy501; + goto yy522; + } else { + if (yych <= 'X') { + if (yych <= 'W') goto yy501; + goto yy523; + } else { + if (yych == '\\') goto yy505; + goto yy501; + } + } +yy510: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= ',') { + if (yych == '+') goto yy510; + goto yy501; + } else { + if (yych <= '-') goto yy510; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy493; + goto yy501; + } +yy512: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '9') { + if (yych == '.') goto yy524; + if (yych <= '/') goto yy501; + goto yy512; + } else { + if (yych <= 'Z') { + if (yych <= '@') goto yy501; + goto yy512; + } else { + if (yych == '_') goto yy512; + goto yy501; + } + } +yy514: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yy516: + yyaccept = 2; + YYMARKER = ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy518; + if (yych <= '9') goto yy516; + if (yych == 'E') goto yy526; +yy518: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_REAL); continue; } +yy519: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_BINARY); continue; } +yy521: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yy505; + goto yy501; +yy522: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yy528; + goto yy501; +yy523: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '3') { + if (yych == '2') goto yy529; + goto yy501; + } else { + if (yych <= '4') goto yy530; + if (yych == '\\') goto yy531; + goto yy501; + } +yy524: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_ENUMERATION); continue; } +yy526: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= ',') { + if (yych == '+') goto yy526; + goto yy501; + } else { + if (yych <= '-') goto yy526; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy532; + goto yy501; + } +yy528: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '[') { + if (yych <= 0x001F) goto yy501; + if (yych <= 'Z') goto yy505; + goto yy501; + } else { + if (yych == ']') goto yy501; + if (yych <= '~') goto yy505; + goto yy501; + } +yy529: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yy534; + goto yy501; +yy530: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yy535; + goto yy501; +yy531: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy536; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy536; + goto yy501; +yy532: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy518; + if (yych <= '9') goto yy532; + goto yy518; +yy534: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy537; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy537; + goto yy501; +yy535: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy538; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy538; + goto yy501; +yy536: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy505; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy505; + goto yy501; +yy537: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy539; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy539; + goto yy501; +yy538: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy540; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy540; + goto yy501; +yy539: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy541; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy541; + goto yy501; +yy540: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy542; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy542; + goto yy501; +yy541: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy543; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy543; + goto yy501; +yy542: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy544; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy544; + goto yy501; +yy543: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy537; + goto yy501; + } else { + if (yych <= 'F') goto yy537; + if (yych == '\\') goto yy545; + goto yy501; + } +yy544: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy546; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy546; + goto yy501; +yy545: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == 'X') goto yy547; + goto yy501; +yy546: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy548; + if (yych <= '@') goto yy501; + if (yych <= 'F') goto yy548; + goto yy501; +yy547: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '0') goto yy521; + goto yy501; +yy548: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy549; + if (yych <= '@') goto yy501; + if (yych >= 'G') goto yy501; +yy549: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy550; + if (yych <= '@') goto yy501; + if (yych >= 'G') goto yy501; +yy550: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yy501; + if (yych <= '9') goto yy538; + goto yy501; + } else { + if (yych <= 'F') goto yy538; + if (yych == '\\') goto yy545; + goto yy501; + } +} + + } + + PUSH_TERMINAL(p->stack, lpop(in, T_KEYWORD)); + PUSH_TERMINAL_EXT(n, p->stack, lpop(in, '(')); + + if (LOOKAHEAD(in->sym[0], '(', T_KEYWORD, T_VARIANT)) + p21_parameter_list(p, act); + + PUSH_TERMINAL_EXT(n, p->stack, lpop(in, ')')); + + if (p->error) + goto err; + + /* user action */ + if (act->simple_record_cb) + act->simple_record_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_SIMPLERECORD}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "simple_record << 12 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_SIMPLERECORD); + else default_error_handler(p, bsp, P_SIMPLERECORD); + recover(in, ';', ')', T_KEYWORD); +} + +void p21_simple_record_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + p21_simple_record(p, act); + + do { + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= ')') { + if (yych <= '\r') { + if (yych == '\n') goto yy555; + if (yych >= '\r') goto yy557; + } else { + if (yych <= ' ') { + if (yych >= ' ') goto yy558; + } else { + if (yych <= '!') goto yy561; + if (yych >= ')') goto yy562; + } + } + } else { + if (yych <= 'Z') { + if (yych == '/') goto yy564; + if (yych >= 'A') goto yy565; + } else { + if (yych <= '_') { + if (yych >= '_') goto yy565; + } else { + if (yych <= '`') goto yy553; + if (yych <= 'z') goto yy565; + } + } + } +yy553: + ++YYCURSOR; +yy554: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yy555: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yy557: + yych = *++YYCURSOR; + if (yych == '\n') goto yy555; + goto yy554; +yy558: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yy558; + { n = in->cur - in->sp; } + { continue; } +yy561: + yych = *++YYCURSOR; + if (yych <= '^') { + if (yych <= '@') goto yy554; + if (yych <= 'Z') goto yy565; + goto yy554; + } else { + if (yych == '`') goto yy554; + if (yych <= 'z') goto yy565; + goto yy554; + } +yy562: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(')'); continue; } +yy564: + yych = *++YYCURSOR; + if (yych == '*') goto yy568; + goto yy554; +yy565: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= 'Z') { + if (yych <= '/') goto yy567; + if (yych <= '9') goto yy565; + if (yych >= 'A') goto yy565; + } else { + if (yych <= '_') { + if (yych >= '_') goto yy565; + } else { + if (yych <= '`') goto yy567; + if (yych <= 'z') goto yy565; + } + } +yy567: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_KEYWORD); continue; } +yy568: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + if (!LOOKAHEAD(in->sym[0], T_KEYWORD)) + break; + p21_simple_record(p, act); + } while (1); + + if (p->error) + goto err; + + /* user action */ + if (act->simple_record_list_cb) + act->simple_record_list_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "simple_record_list << 13 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, ')', ';'); +} + +void p21_parameter(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 2) { + in->sp = in->cur; + +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= ')') { + if (yych <= ' ') { + if (yych <= '\f') { + if (yych == '\n') goto yya574; + } else { + if (yych <= '\r') goto yya576; + if (yych >= ' ') goto yya577; + } + } else { + if (yych <= '#') { + if (yych <= '!') goto yya580; + if (yych <= '"') goto yya581; + goto yya582; + } else { + if (yych <= '$') goto yya583; + if (yych <= '&') goto yya572; + if (yych <= '\'') goto yya585; + goto yya586; + } + } + } else { + if (yych <= '9') { + if (yych <= ',') { + if (yych <= '*') goto yya588; + if (yych <= '+') goto yya590; + goto yya586; + } else { + if (yych <= '-') goto yya590; + if (yych <= '.') goto yya591; + if (yych <= '/') goto yya592; + goto yya593; + } + } else { + if (yych <= '^') { + if (yych <= '@') goto yya572; + if (yych <= 'Z') goto yya596; + } else { + if (yych == '`') goto yya572; + if (yych <= 'z') goto yya596; + } + } + } +yya572: + ++YYCURSOR; +yya573: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yya574: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yya576: + yych = *++YYCURSOR; + if (yych == '\n') goto yya574; + goto yya573; +yya577: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yya577; + { n = in->cur - in->sp; } + { continue; } +yya580: + yych = *++YYCURSOR; + if (yych <= '^') { + if (yych <= '@') goto yya573; + if (yych <= 'Z') goto yya596; + goto yya573; + } else { + if (yych == '`') goto yya573; + if (yych <= 'z') goto yya596; + goto yya573; + } +yya581: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '/') goto yya573; + if (yych <= '3') goto yya599; + goto yya573; +yya582: + yych = *++YYCURSOR; + if (yych <= '/') goto yya573; + if (yych <= '9') goto yya602; + goto yya573; +yya583: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_EMPTY); continue; } +yya585: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '[') { + if (yych <= 0x001F) goto yya573; + if (yych <= 'Z') goto yya606; + goto yya573; + } else { + if (yych == ']') goto yya573; + if (yych <= '~') goto yya606; + goto yya573; + } +yya586: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(*in->sp); continue; } +yya588: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_DERIVED); continue; } +yya590: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= ',') { + if (yych == '+') goto yya610; + goto yya573; + } else { + if (yych <= '-') goto yya610; + if (yych <= '/') goto yya573; + if (yych <= '9') goto yya593; + goto yya573; + } +yya591: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if (yych <= '@') goto yya573; + if (yych <= 'Z') goto yya612; + if (yych == '_') goto yya612; + goto yya573; +yya592: + yych = *++YYCURSOR; + if (yych == '*') goto yya614; + goto yya573; +yya593: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '.') goto yya616; + if (yych <= '/') goto yya595; + if (yych <= '9') goto yya593; +yya595: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_INTEGER); continue; } +yya596: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= 'Z') { + if (yych <= '/') goto yya598; + if (yych <= '9') goto yya596; + if (yych >= 'A') goto yya596; + } else { + if (yych <= '_') { + if (yych >= '_') goto yya596; + } else { + if (yych <= '`') goto yya598; + if (yych <= 'z') goto yya596; + } + } +yya598: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_KEYWORD); continue; } +yya599: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') { + if (yych == '"') goto yya619; + } else { + if (yych <= '9') goto yya599; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya599; + } +yya601: + YYCURSOR = YYMARKER; + if (yyaccept <= 1) { + if (yyaccept == 0) { + goto yya573; + } else { + goto yya608; + } + } else { + goto yya618; + } +yya602: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya604; + if (yych <= '9') goto yya602; +yya604: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_EID); continue; } +yya605: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yya606: + if (yych <= 'Z') { + if (yych <= 0x001F) goto yya601; + if (yych != '\'') goto yya605; + } else { + if (yych <= '\\') { + if (yych <= '[') goto yya601; + goto yya609; + } else { + if (yych <= ']') goto yya601; + if (yych <= '~') goto yya605; + goto yya601; + } + } + yyaccept = 1; + YYMARKER = ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\'') goto yya605; +yya608: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_STRING); continue; } +yya609: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= 'S') { + if (yych <= '@') goto yya601; + if (yych <= 'I') goto yya621; + if (yych <= 'R') goto yya601; + goto yya622; + } else { + if (yych <= 'X') { + if (yych <= 'W') goto yya601; + goto yya623; + } else { + if (yych == '\\') goto yya605; + goto yya601; + } + } +yya610: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= ',') { + if (yych == '+') goto yya610; + goto yya601; + } else { + if (yych <= '-') goto yya610; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya593; + goto yya601; + } +yya612: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '9') { + if (yych == '.') goto yya624; + if (yych <= '/') goto yya601; + goto yya612; + } else { + if (yych <= 'Z') { + if (yych <= '@') goto yya601; + goto yya612; + } else { + if (yych == '_') goto yya612; + goto yya601; + } + } +yya614: + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +yya616: + yyaccept = 2; + YYMARKER = ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya618; + if (yych <= '9') goto yya616; + if (yych == 'E') goto yya626; +yya618: + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_REAL); continue; } +yya619: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_BINARY); continue; } +yya621: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yya605; + goto yya601; +yya622: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yya628; + goto yya601; +yya623: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '3') { + if (yych == '2') goto yya629; + goto yya601; + } else { + if (yych <= '4') goto yya630; + if (yych == '\\') goto yya631; + goto yya601; + } +yya624: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(T_VARIANT, V_ENUMERATION); continue; } +yya626: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= ',') { + if (yych == '+') goto yya626; + goto yya601; + } else { + if (yych <= '-') goto yya626; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya632; + goto yya601; + } +yya628: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '[') { + if (yych <= 0x001F) goto yya601; + if (yych <= 'Z') goto yya605; + goto yya601; + } else { + if (yych == ']') goto yya601; + if (yych <= '~') goto yya605; + goto yya601; + } +yya629: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yya634; + goto yya601; +yya630: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '\\') goto yya635; + goto yya601; +yya631: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya636; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya636; + goto yya601; +yya632: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya618; + if (yych <= '9') goto yya632; + goto yya618; +yya634: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya637; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya637; + goto yya601; +yya635: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya638; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya638; + goto yya601; +yya636: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya605; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya605; + goto yya601; +yya637: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya639; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya639; + goto yya601; +yya638: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya640; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya640; + goto yya601; +yya639: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya641; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya641; + goto yya601; +yya640: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya642; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya642; + goto yya601; +yya641: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya643; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya643; + goto yya601; +yya642: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya644; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya644; + goto yya601; +yya643: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya637; + goto yya601; + } else { + if (yych <= 'F') goto yya637; + if (yych == '\\') goto yya645; + goto yya601; + } +yya644: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya646; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya646; + goto yya601; +yya645: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == 'X') goto yya647; + goto yya601; +yya646: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya648; + if (yych <= '@') goto yya601; + if (yych <= 'F') goto yya648; + goto yya601; +yya647: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == '0') goto yya621; + goto yya601; +yya648: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya649; + if (yych <= '@') goto yya601; + if (yych >= 'G') goto yya601; +yya649: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya650; + if (yych <= '@') goto yya601; + if (yych >= 'G') goto yya601; +yya650: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych <= '@') { + if (yych <= '/') goto yya601; + if (yych <= '9') goto yya638; + goto yya601; + } else { + if (yych <= 'F') goto yya638; + if (yych == '\\') goto yya645; + goto yya601; + } +} + + } + + if (LOOKAHEAD(in->sym[0], T_VARIANT)) { + PUSH_TERMINAL(p->stack, lpop(in, T_VARIANT)); + } else { + if (LOOKAHEAD(in->sym[0], T_KEYWORD)) { + PUSH_TERMINAL(p->stack, lpop(in, T_KEYWORD)); + PUSH_TERMINAL(p->stack, lpop(in, '(')); + p21_parameter(p, act); + } else { + PUSH_TERMINAL(p->stack, lpop(in, '(')); + if (LOOKAHEAD(in->sym[0], '(', T_KEYWORD, T_VARIANT)) { + p21_parameter_list(p, act); + } + } + while (in->nsym < 1) { + in->sp = in->cur; + +{ + YYCTYPE yych; + if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if (yych <= 0x001F) { + if (yych <= '\n') { + if (yych >= '\n') goto yyb655; + } else { + if (yych == '\r') goto yyb657; + } + } else { + if (yych <= ')') { + if (yych <= ' ') goto yyb658; + if (yych >= ')') goto yyb661; + } else { + if (yych == '/') goto yyb663; + } + } + ++YYCURSOR; +yyb654: + { n = in->cur - in->sp; } + { YYCURSOR--; break; } +yyb655: + ++YYCURSOR; + { n = in->cur - in->sp; } + { in->lineno++; continue; } +yyb657: + yych = *++YYCURSOR; + if (yych == '\n') goto yyb655; + goto yyb654; +yyb658: + ++YYCURSOR; + if (YYLIMIT <= YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if (yych == ' ') goto yyb658; + { n = in->cur - in->sp; } + { continue; } +yyb661: + ++YYCURSOR; + { n = in->cur - in->sp; } + { PUSH_SYMBOL(')'); continue; } +yyb663: + yych = *++YYCURSOR; + if (yych != '*') goto yyb654; + ++YYCURSOR; + { n = in->cur - in->sp; } + { lex_comment(in); continue; } +} + + } + PUSH_TERMINAL(p->stack, lpop(in, ')')); + } + + if (p->error) + goto err; + + /* user action */ + if (act->parameter_cb) + act->parameter_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_PARAMETER}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "parameter << 14 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_PARAMETER); + else default_error_handler(p, bsp, P_PARAMETER); + recover(in, ')', ',', ';'); +} + +void mock_error(P21Parser *, int, uint8_t); +void mock_ud_init(void *); +void mock_ud_exit(void *); +void mock_exchange_file(P21Parser *, int, void *); +void mock_header_start(P21Parser *, int, void *); +void mock_header_entity_list(P21Parser *, int, void *); +void mock_data_section_list(P21Parser *, int, void *); +void mock_data_start(P21Parser *, int, void *); +void mock_header_entity(P21Parser *, int, void *); +void mock_simple_entity_instance(P21Parser *, int, void *); +void mock_complex_entity_instance(P21Parser *, int, void *); +void mock_parameter_list(P21Parser *, int, void *); +void mock_parameter(P21Parser *, int, void *); +void mock_entity_instance_list(P21Parser *, int, void *); +void mock_entity_instance(P21Parser *, int, void *); +void mock_simple_record_list(P21Parser *, int, void *); +void mock_simple_record(P21Parser *, int, void *); +void mock_noop(P21Parser *, int, void *); + +typedef struct { + sqlite3 *db; + sqlite3_stmt *sec_stmt; + sqlite3_stmt *sei_stmt; + sqlite3_stmt *cei_stmt; + sqlite3_stmt *hei_stmt; + int section_idx; +} P21UserData; + +P21UserData mockdata = {0}; + +P21ParserActions mockact = { + .userdata = &mockdata, + .error_cb = mock_error, + .ud_init_cb = mock_ud_init, + .ud_exit_cb = mock_ud_exit, + .header_start_cb = mock_header_start, + .data_start_cb = mock_data_start, + .exchange_file_cb = NULL, + .header_entity_list_cb = NULL, + .data_section_list_cb = NULL, + .header_entity_cb = mock_header_entity, + .simple_entity_instance_cb = mock_simple_entity_instance, + .complex_entity_instance_cb = mock_complex_entity_instance, + .parameter_list_cb = mock_noop, + .parameter_cb = mock_noop, + .entity_instance_list_cb = NULL, + .entity_instance_cb = NULL, + .simple_record_list_cb = mock_noop, + .simple_record_cb = mock_noop +}; + +void mock_error(P21Parser *p, int bsp, uint8_t cxt) { + switch (cxt) { + case P_SIMPLEENTITY: + case P_COMPLEXENTITY: + case P_HEADERENTITY: + dprintf("caught error: '%c'\n", cxt); + p->error = false; + drop(p->stack, p->stack->idx_top - bsp - 1); + break; + default: + p->error = true; + break; + } +} + + +void mock_ud_init(void *d) { + P21UserData *ud = d; + char ddl_sql[] = + "PRAGMA foreign_keys = ON;\n" + "CREATE TABLE entity_enum (type TEXT(1) PRIMARY KEY);\n" + "INSERT INTO entity_enum (type) VALUES ('S'), ('C');\n" + "CREATE TABLE section_enum (type TEXT(1) PRIMARY KEY);\n" + "INSERT INTO section_enum (type) VALUES ('D'), ('H');\n" + + "CREATE TABLE section_table (\n" + " id INTEGER PRIMARY KEY,\n" + " lineno INTEGER NOT NULL,\n" + " section_type TEXT(1) NOT NULL REFERENCES section_enum(type)\n" + ");\n" + + "CREATE TABLE section_headers (\n" + " id INTEGER PRIMARY KEY,\n" + " type_name TEXT COLLATE NOCASE,\n" + " raw_data TEXT NOT NULL,\n" + " lineno INTEGER NOT NULL,\n" + " fk_section INTEGER NOT NULL REFERENCES section_table(id)\n" + ");\n" + + "CREATE TABLE data_table (\n" + " id TEXT PRIMARY KEY,\n" + " type_name TEXT COLLATE NOCASE,\n" + " raw_data TEXT NOT NULL,\n" + " lineno INTEGER NOT NULL,\n" + " entity_type TEXT(1) NOT NULL REFERENCES entity_enum(type),\n" + " fk_section INTEGER NOT NULL REFERENCES section_table(id)\n" + ") WITHOUT ROWID;\n" + + "BEGIN DEFERRED TRANSACTION;"; + + char sei_sql[] = "INSERT INTO data_table VALUES (?,?,?,?,'S',?)"; + char cei_sql[] = "INSERT INTO data_table VALUES (?,NULL,?,?,'C',?)"; + char hei_sql[] = "INSERT INTO section_headers(type_name, raw_data, lineno, fk_section) VALUES (?, ?, ?, ?)"; + int rc; + + rc = sqlite3_open_v2(":memory:", &ud->db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); + + /* TODO: read ddl sql from external file */ + rc = sqlite3_exec(ud->db, ddl_sql, NULL, NULL, NULL); + + rc |= sqlite3_prepare_v3(ud->db, sei_sql, sizeof sei_sql, SQLITE_PREPARE_PERSISTENT, &ud->sei_stmt, NULL); + rc |= sqlite3_prepare_v3(ud->db, cei_sql, sizeof cei_sql, SQLITE_PREPARE_PERSISTENT, &ud->cei_stmt, NULL); + rc |= sqlite3_prepare_v3(ud->db, hei_sql, sizeof hei_sql, SQLITE_PREPARE_PERSISTENT, &ud->hei_stmt, NULL); + + if (rc != SQLITE_OK) + exit(1); + + ud->section_idx = 0; +} + +void mock_ud_exit(void *d) { + P21UserData *ud = d; + int rc; + char ddl_sql[] = + "CREATE INDEX ix_type_name ON data_table(type_name);\n" + "CREATE INDEX ix_entity_type ON data_table(entity_type);\n" + "CREATE INDEX ix_fk_section ON data_table(fk_section);"; + + rc = sqlite3_finalize(ud->sei_stmt); + rc |= sqlite3_finalize(ud->cei_stmt); + rc |= sqlite3_finalize(ud->hei_stmt); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_exec(ud->db, "COMMIT TRANSACTION", NULL, NULL, NULL); + if (rc != SQLITE_OK) goto err; + + /* TODO: benchmark index creation here vs on db init */ + rc = sqlite3_exec(ud->db, ddl_sql, NULL, NULL, NULL); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_close(ud->db); + if (rc != SQLITE_OK) goto err; + + return; +err: + dprintf("db error\n"); + exit(1); +} + +void mock_exchange_file(P21Parser *p, int bsp, void *d) { Stack *s = p->stack; } +void mock_header_start(P21Parser *p, int bsp, void *d) { + char sec_sql[] = "INSERT INTO section_table VALUES(?,?,'H')"; + Stack *s = p->stack; + P21UserData *ud = d; + Symbol *t = s->items + bsp; + sqlite3_stmt *stmt; + int rc; + + rc = sqlite3_prepare_v2(ud->db, sec_sql, sizeof sec_sql, &stmt, NULL); + if (rc != SQLITE_OK) goto err; + + rc |= sqlite3_bind_int(stmt, 1, ++ud->section_idx); + rc |= sqlite3_bind_int(stmt, 2, t->lineno); + if (rc != SQLITE_OK) goto err; + + rc |= sqlite3_step(stmt); + if (rc != SQLITE_DONE) goto err; + + sqlite3_finalize(stmt); + + /* + s->items[bsp] = (Symbol){P_HEADERSECTION}; + drop(s, s->idx_top - bsp - 1); + */ + + return; + +err: + dprintf("db error\n"); + exit(1); +} +void mock_header_entity_list(P21Parser *p, int bsp, void *d) { Stack *s = p->stack; } +void mock_data_section_list(P21Parser *p, int bsp, void *d) { Stack *s = p->stack; } +void mock_data_start(P21Parser *p, int bsp, void *d) { + char sec_sql[] = "INSERT INTO section_table VALUES(?,?,'D')"; + Stack *s = p->stack; + P21UserData *ud = d; + Symbol *t = s->items + bsp; + sqlite3_stmt *stmt; + int rc; + + rc = sqlite3_prepare_v2(ud->db, sec_sql, sizeof sec_sql, &stmt, NULL); + if (rc != SQLITE_OK) goto err; + + rc |= sqlite3_bind_int(stmt, 1, ++ud->section_idx); + rc |= sqlite3_bind_int(stmt, 2, t->lineno); + if (rc != SQLITE_OK) goto err; + + rc |= sqlite3_step(stmt); + if (rc!= SQLITE_DONE) goto err; + + sqlite3_finalize(stmt); + + return; + +err: + dprintf("db error\n"); + exit(1); +} + +void mock_header_entity(P21Parser *p, int bsp, void *d) { + Stack *s = p->stack; + P21UserData *ud = d; + HeaderEntity e = {s->items + bsp, s->items + bsp + 1}; + size_t i, nargs = e.args->n; + unsigned char *basemrk = p->in->basemrk; + ptrdiff_t ep; + int rc; + + /* rewrite (normalise) args member before bind */ + e.args->offset = (e.args + 1)->offset; + e.args->n = (e.args + 1)->n; + for (i = 2, ep = e.args->offset + 1; i < nargs; i++) { + Symbol *t = e.args + i; + if (t->token == '(') t->n = 1; + if (ep != t->offset) memmove(basemrk + ep, basemrk + t->offset, t->n); + ep += t->n; + } + e.args->n = ep - e.args->offset; + + rc = sqlite3_reset(ud->hei_stmt); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_bind_text(ud->hei_stmt, 1, basemrk + e.kw->offset, e.kw->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_text(ud->hei_stmt, 2, basemrk + e.args->offset, e.args->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_int(ud->hei_stmt, 3, e.kw->lineno); + rc |= sqlite3_bind_int(ud->hei_stmt, 4, ud->section_idx); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_step(ud->hei_stmt); + if (rc != SQLITE_DONE) goto err; + + p->hold = false; + return; + +err: + mock_error(p, bsp, P_HEADERENTITY); + dprintf("db error\n"); +} + +void mock_simple_entity_instance(P21Parser *p, int bsp, void *d) { + Stack *s = p->stack; + P21UserData *ud = d; + SimpleEntity e = {s->items + bsp, s->items + bsp + 1, s->items + bsp + 2, s->items + bsp + 3}; + size_t i, nargs = e.args->n; + unsigned char *basemrk = p->in->basemrk; + ptrdiff_t ep; + int rc; + + /* rewrite (normalise) args before bind */ + e.args->offset = (e.args + 1)->offset; + e.args->n = (e.args + 1)->n; + for (i = 2, ep = e.args->offset + e.args->n; i < nargs; i++) { + Symbol *t = e.args + i; + if (t->token == '(') t->n = 1; + if (ep != t->offset) memmove(basemrk + ep, basemrk + t->offset, t->n); + ep += t->n; + } + e.args->n = ep - e.args->offset; + + /* */ + rc = sqlite3_reset(ud->sei_stmt); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_bind_text(ud->sei_stmt, 1, basemrk + e.eid->offset, e.eid->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_text(ud->sei_stmt, 2, basemrk + e.kw->offset, e.kw->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_text(ud->sei_stmt, 3, basemrk + e.args->offset, e.args->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_int(ud->sei_stmt, 4, e.eid->lineno); + rc |= sqlite3_bind_int(ud->sei_stmt, 5, ud->section_idx); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_step(ud->sei_stmt); + if (rc != SQLITE_DONE) goto err; + + p->hold = false; + + return; + +err: + mock_error(p, bsp, P_SIMPLEENTITY); + dprintf("db error\n"); +} + + +void mock_complex_entity_instance(P21Parser *p, int bsp, void *d) { + Stack *s = p->stack; + P21UserData *ud = d; + ComplexEntity e = {s->items + bsp, s->items + bsp + 1, s->items + bsp + 2}; + size_t i, nsubsupers = e.subsupers->n; + unsigned char *basemrk = p->in->basemrk; + ptrdiff_t ep; + int rc; + + /* rewrite (normalise) list before bind */ + for (i = 1, ep = e.subsupers->offset + 1; i < nsubsupers; i++) { + Symbol *t = e.subsupers + i; + if (t->token == '(') t->n = 1; + if (ep != t->offset) memmove(basemrk + ep, basemrk + t->offset, t->n); + ep += t->n; + } + e.subsupers->n = ep - e.subsupers->offset; + + rc = sqlite3_reset(ud->cei_stmt); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_bind_text(ud->cei_stmt, 1, basemrk + e.eid->offset, e.eid->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_text(ud->cei_stmt, 2, basemrk + e.subsupers->offset, e.subsupers->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_int(ud->cei_stmt, 3, e.eid->lineno); + rc |= sqlite3_bind_int(ud->cei_stmt, 4, ud->section_idx); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_step(ud->cei_stmt); + if (rc != SQLITE_DONE) goto err; + + p->hold = false; + return; + +err: + mock_error(p, bsp, P_COMPLEXENTITY); + dprintf("db error \n"); +} + +void mock_parameter_list(P21Parser *p, int bsp, void *d) { } +void mock_parameter(P21Parser *p, int bsp, void *d) { } +void mock_entity_instance_list(P21Parser *p, int bsp, void *d) { } +void mock_entity_instance(P21Parser *p, int bsp, void *d) { } +void mock_simple_record_list(P21Parser *p, int bsp, void *d) { } +void mock_simple_record(P21Parser *p, int bsp, void *d) {} + +void mock_noop(P21Parser *p, int bsp, void *d) { + p->hold = true; +} + +int main(char *argv[], int argc) { + const char *paths[] = { + "/home/chorler/projects/src/stepcode/test/p21/test_array_bounds_FAIL1.p21", + "/home/chorler/projects/src/stepcode/test/p21/comments.p21", + "/home/chorler/projects/src/stepcode/test/p21/test_inverse_attr.p21", + "/home/chorler/projects/src/stepcode/test/p21/missing_and_required.p21", + "/home/chorler/projects/src/stepcode/test/p21/test_array_bounds.p21", + "/home/chorler/projects/src/stepcode/test/p21/test_inherit_inverse.p21", + "/home/chorler/projects/src/stepcode/data/ap214e3/as1-oc-214.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/dm1-id-214.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/MAINBODY.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/HEAD_BACK.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/HEAD_FRONT.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/TAIL.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/MAINBODY_FRONT.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/FOOT_BACK_000.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/FOOT_FRONT_000.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/s1-c5-214.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/MAINBODY_BACK.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/HEAD.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/TAIL_TURBINE.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/TAIL_MIDDLE_PART.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/FOOT.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/sg1-c5-214.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/io1-cm-214.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS7-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS1Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS2-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS1Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS3-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS10Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS2Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS8-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS3Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS4Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS7Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS4Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS10Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS3Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS8Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS4-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS7Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS2Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS8Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS10-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS1-out.stp" + }; + + P21Parser myp; + P21UserData mydata; + FILE *fp; + memset(&mydata, 0, sizeof mydata); + + for (unsigned int i = 0; i < (sizeof paths / sizeof paths[0]); i++) { + fp = fopen(paths[i], "rb"); + if (!fp) { fprintf(stderr, "failed to read input: %s\n", paths[i]); continue; } + else { fprintf(stderr, "processing: %s\n", paths[i]); } + p21_init(&myp, fp); + p21_parse(&myp, &mockact); + } +} diff --git a/src/exp2python/python/stepcode/_cPart21.l b/src/exp2python/python/stepcode/_cPart21.l new file mode 100644 index 000000000..2a8ded85a --- /dev/null +++ b/src/exp2python/python/stepcode/_cPart21.l @@ -0,0 +1,1602 @@ +/* + * STEP Part 21 Parser + * + * Copyright (c) 2020, Christopher HORLER (cshorler@googlemail.com) + * + * All rights reserved. + * + * This file is part of the STEPCODE project. + * + * 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. + * + * Neither the name of the nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define YYCTYPE unsigned char +#define YYCURSOR in->cur +#define YYLIMIT in->lim +#define YYMARKER in->mrk +#define YYCTXMARKER in->ctxmrk +#define YYFILL(n) do { \ + if (fill(in, n) != 0) { \ + fprintf(stderr, "lexer fill(...) failed, exiting\n"); \ + exit(1); \ + } \ + } while (0) + +/*!max:re2c*/ +#define INIT_BUF_SZ 4096 +#define INIT_STACK_SZ 64 + +/* reserved literals '(' ')' ';' '=' */ +#define T_P21_START 'S' +#define T_P21_END 'X' +#define T_HEADER 'H' +#define T_DATA 'D' +#define T_ENDSEC 'E' +#define T_EID 'I' +#define T_KEYWORD 'K' +#define T_VARIANT 'V' +#define T_EOF '\x00' +#define T_ERROR '\x01' + +#define V_REAL 'r' +#define V_INTEGER 'i' +#define V_STRING 's' +#define V_BINARY 'b' +#define V_ENUMERATION 'e' +#define V_EID T_EID +#define V_DERIVED '*' +#define V_EMPTY '$' + +#define P_FILE 'f' +#define P_HEADERSECTION 'h' +#define P_DATASECTION 'd' +#define P_HEADERENTITY 'x' +#define P_SIMPLEENTITY 's' +#define P_COMPLEXENTITY 'c' +#define P_SIMPLERECORD 'u' +#define P_LIST 'l' +#define P_PARAMETER 'p' + +int debug = 1; +#define dprintf(fmt, ...) \ + do { if (debug) fprintf(stderr, "%s:%3d " fmt, __FILE__, __LINE__, ##__VA_ARGS__); } while (0) + +/* ppfu https://stackoverflow.com/a/11763277/1162349 */ +#define GET_MACRO(_1, _2, _3, _4, NAME, ...) NAME +#define _EXPAND(x) x + +/* for lookahead */ +#define PUSH_SYMBOL(...) _EXPAND(GET_MACRO(__VA_ARGS__, _4, _3, _PUSH_SYMBOL2, _PUSH_SYMBOL1)(__VA_ARGS__)) +#define _PUSH_SYMBOL1(token) in->sym[in->nsym++] = (Symbol){(token), 0, n, in->lineno, in->sp - in->basemrk} +#define _PUSH_SYMBOL2(token, vtype) in->sym[in->nsym++] = (Symbol){(token), (vtype), n, in->lineno, in->sp - in->basemrk} + +/* for parse stack */ +#define PUSH_TERMINAL(stack, sym) do { \ + Symbol it = (sym); \ + push((stack), it); \ + if (it.token == T_ERROR) goto err; \ + } while (0) + +#define PUSH_TERMINAL_EXT(cxt, stack, sym) do { \ + Symbol it = (sym); \ + push((stack), it); \ + if (it.token == T_ERROR) goto err; \ + else if (it.token == '(') (cxt) = (stack)->idx_top - 1; \ + else if (it.token == ')') (stack)->items[(cxt)].n = (stack)->idx_top - (cxt) - 1; \ + } while (0) + +/* test for one in a set of 1 to 4 e.g. {t0, t1, t2, t3} */ +#define LOOKAHEAD(x, ...) _EXPAND(GET_MACRO(__VA_ARGS__, _LOOKAHEAD4, _LOOKAHEAD3, _LOOKAHEAD2, _LOOKAHEAD1)(x, __VA_ARGS__)) +#define _LOOKAHEAD1(x, t0) ((t0) == (x).token) +#define _LOOKAHEAD2(x, t0, t1) ((t0) == (x).token || (t1) == (x).token) +#define _LOOKAHEAD3(x, t0, t1, t2) (_LOOKAHEAD2(x, t0, t1) || (t2) == (x).token) +#define _LOOKAHEAD4(x, t0, t1, t2, t3) (_LOOKAHEAD2(x, t0, t1) || _LOOKAHEAD2(x, t2, t3)) + + +/*!rules:re2c + ascii_encoding = [][!"*$%&.#+,\-()?/:;<=>@{}|^`~0-9a-zA-Z_ ] | "''" | "\\\\" ; + page_encoding = "\\" [A-I] "\\" | "\\S\\" [][!"'*$%&.#+,\-()?/:;<=>@{}|^`~0-9a-zA-Z_\\ ] ; + hex_encoding = "\\X2\\" ([0-9A-F]{4})+ "\\X0\\" | "\\X4\\" ([0-9A-F]{8})+ "\\X0\\" ; + byte_encoding = "\\X\\" [0-9A-F]{2} ; + + NL = ("\n" | "\r\n") ; + PUNCTUATION = [ ;()/] ; + + P21_START = "ISO-10303-21;" ; + P21_END = "END-ISO-10303-21;" ; + DATA = "DATA" ; + HEADER = "HEADER;" ; + ENDSEC = "ENDSEC;" ; + + WS = " " ; + KEYWORD = "!"? [A-Za-z_] [0-9A-Za-z_]* ; + REAL = [+-]* [0-9] [0-9]* "." [0-9]* ("E" [+-]* [0-9] [0-9]*)? ; + INTEGER = [+-]* [0-9] [0-9]* ; + STRING = "'" (ascii_encoding | page_encoding | hex_encoding | byte_encoding )* "'" ; + BINARY = '"' [0-3] [0-9A-F]* '"' ; + ENUMERATION = "." [A-Z_] [A-Z0-9_]* "." ; + EID = "#" [0-9]+ ; + + { n = in->cur - in->sp; } + WS+ { continue; } + NL { in->lineno++; continue; } + "/*" { lex_comment(in); continue; } + * { YYCURSOR--; break; } + + */ + + +/* lexeme */ +typedef struct { + uint8_t token; + union { + uint8_t vtype; + uint8_t errtoken; + }; + uint16_t n; + uint32_t lineno; + union { + ptrdiff_t offset; /* from basemrk */ + void *data; /* production allocation if applicable */ + }; +} Symbol; + +typedef struct SimpleRecord_ { + Symbol *kw; /* 'KEYWORD' */ + Symbol *args;/* '(' */ +} SimpleRecord; + +typedef struct SimpleRecord_ HeaderEntity; + +typedef struct { + Symbol *eid; /* '#' */ + Symbol *eq; /* '=' */ + Symbol *kw; /* 'KEYWORD' */ + Symbol *args;/* '(' */ +} SimpleEntity; + +typedef struct { + Symbol *eid; /* '#' */ + Symbol *eq; /* '=' */ + Symbol *subsupers;/* '(' */ +} ComplexEntity; + + +typedef struct { + FILE *file; + size_t bufsz; + unsigned char *cur, *mrk, *ctxmrk, *lim; + unsigned char *sp, *basemrk; + int eof; + uint32_t lineno; + int nsym; + Symbol sym[3]; + unsigned char *buf; +} Input; + +typedef struct { + int idx_top; + int idx_lim; + Symbol *items; +} Stack; + +/* LL(3) parser */ +typedef struct { + bool error; + bool hold; + Input *in; + Stack *stack; +} P21Parser; + +typedef void (p21_action_cb_t) (P21Parser *, int, void *); +typedef void (p21_error_cb_t) (P21Parser *, int, uint8_t); +typedef void (p21_ud_cb_t) (void *); + +typedef struct { + void *userdata; + p21_error_cb_t *error_cb; + p21_ud_cb_t *ud_init_cb; + p21_ud_cb_t *ud_exit_cb; + p21_action_cb_t *exchange_file_cb; + p21_action_cb_t *header_start_cb; + p21_action_cb_t *header_entity_list_cb; + p21_action_cb_t *data_section_list_cb; + p21_action_cb_t *data_start_cb; + p21_action_cb_t *header_entity_cb; + p21_action_cb_t *simple_entity_instance_cb; + p21_action_cb_t *complex_entity_instance_cb; + p21_action_cb_t *parameter_list_cb; + p21_action_cb_t *parameter_cb; + p21_action_cb_t *entity_instance_list_cb; + p21_action_cb_t *entity_instance_cb; + p21_action_cb_t *simple_record_list_cb; + p21_action_cb_t *simple_record_cb; +} P21ParserActions; + + +void report_error(P21Parser *, const char *); +void _recover(Input *, uint8_t, uint8_t, uint8_t); +Symbol lpop(Input *, uint8_t); + +void p21_parse(P21Parser *, P21ParserActions *); +void p21_exchange_file(P21Parser *, P21ParserActions *); +void p21_header_section(P21Parser *, P21ParserActions *); +void p21_header_entity_list(P21Parser *, P21ParserActions *); +void p21_header_entity(P21Parser *, P21ParserActions *); +void p21_data_section_list(P21Parser *, P21ParserActions *); +void p21_data_section(P21Parser *, P21ParserActions *); +void p21_entity_instance(P21Parser *, P21ParserActions *); +void p21_simple_entity_instance(P21Parser *, P21ParserActions *); +void p21_complex_entity_instance(P21Parser *, P21ParserActions *); +void p21_entity_instance_list(P21Parser *, P21ParserActions *); +void p21_parameter(P21Parser *, P21ParserActions *); +void p21_parameter_list(P21Parser *, P21ParserActions *); +void p21_simple_record(P21Parser *, P21ParserActions *); +void p21_simple_record_list(P21Parser *, P21ParserActions *); + + +void push(Stack *stack, Symbol it) { + if (stack->idx_top == stack->idx_lim) { + Symbol *nitems = realloc(stack->items, 2 * stack->idx_lim * sizeof stack->items[0]); + if (!nitems) { + fprintf(stderr, "failed to grow parser stack, memory exhausted\n"); + exit(1); + } + stack->items = nitems; + stack->idx_lim *= 2; + } + + stack->items[stack->idx_top++] = it; +} + +/* mock implementations */ +void drop(Stack *stack, uint32_t n) { + assert(stack->idx_top >= n); + stack->idx_top -= n; +} + +void unwind(Stack *stack, int bsp) { + stack->idx_top = bsp; +} + +Symbol *pop(Stack *stack) { + assert(stack->idx_top >= 1); + stack->idx_top--; + return stack->items + stack->idx_top; +} + +Symbol *peek(Stack *stack) { + assert(stack->idx_top >= 1); + return stack->items + stack->idx_top - 1; +} + +Symbol lpop(Input *in, uint8_t token) { + Symbol *stack = in->sym; + Symbol sym = stack[0]; + + /* missing input or unexpected lookahead token */ + if (in->nsym == 0) + return (Symbol){T_ERROR, token, 0, in->lineno}; + else if (sym.token != token) + return (Symbol){T_ERROR, token, 0, sym.lineno}; + + if (!--in->nsym) { + memset(&in->sym[0], 0, sizeof in->sym[0]); + } else { + memmove(&in->sym[0], &in->sym[1], in->nsym * sizeof in->sym[0]); + memset(&in->sym[in->nsym], 0, sizeof in->sym[0]); + } + + return sym; +} + +static int fill(Input *in, size_t need) +{ + size_t free; + unsigned char *newbuf; + + if (in->eof) { + return 1; + } + free = in->basemrk - in->buf; + if (free < need) { + newbuf = realloc(in->buf, 2 * in->bufsz + YYMAXFILL); + if (!newbuf) { + fprintf(stderr, "fatal - buffer memory exhausted, exiting\n"); + return 2; + } + in->bufsz *= 2; + in->lim = newbuf + (in->lim - in->buf); + in->cur = newbuf + (in->cur - in->buf); + in->mrk = newbuf + (in->mrk - in->buf); + in->ctxmrk = newbuf + (in->ctxmrk - in->buf); + in->basemrk = newbuf + (in->basemrk - in->buf); + in->sp = newbuf + (in->sp - in->buf); + in->buf = newbuf; + + /* don't memmove() here! */ + free = (in->buf + in->bufsz) - in->lim; + } else { + memmove(in->buf, in->basemrk, in->lim - in->basemrk); + in->lim -= free; + in->cur -= free; + in->mrk -= free; + in->ctxmrk -= free; + in->basemrk -= free; + in->sp -= free; + } + + in->lim += fread(in->lim, 1, free, in->file); + if (in->lim < in->buf + in->bufsz) { + in->eof = 1; + memset(in->lim, 0, YYMAXFILL); + in->lim += YYMAXFILL; + } + return 0; +} + +static void p21_init(P21Parser *p, FILE *file) +{ + Stack *stack; + Input *in; + + in = malloc(sizeof *in); + if (!in) + goto err; + memset(in, 0, sizeof *in); + in->bufsz = INIT_BUF_SZ; + in->buf = malloc(INIT_BUF_SZ + YYMAXFILL); + if (!in->buf) + goto err; + in->file = file; + in->cur = in->basemrk = in->sp = in->lim = in->buf + INIT_BUF_SZ; + in->lineno = 1; + fill(in, 1); + + stack = malloc(sizeof *stack); + if (!stack) + goto err; + memset(stack, 0, sizeof *stack); + stack->idx_lim = 16; + stack->idx_top = 0; + stack->items = malloc(stack->idx_lim * sizeof stack->items[0]); + if (!stack->items) + goto err; + + p->in = in; + p->stack = stack; + p->error = false; + + return; + +err: + fprintf(stderr, "failed to initialise parser\n"); + exit(1); +} + +/* noop error handler */ +void default_error_handler(P21Parser *p, int bsp, uint8_t t) { + Symbol *sym = peek(p->stack); + if (sym->token == T_ERROR) + pop(p->stack); + push(p->stack, (Symbol){t}); +} + +/* TODO: this needs to be reworked */ +void report_error(P21Parser *p, const char *cxt) { + Input *in = p->in; + Symbol *it = peek(p->stack); + int lineno; + unsigned char *cur; + + fprintf(stderr, cxt); + + if (it->token == T_ERROR) { + fprintf(stderr, " syntax error - line: %d\n", it->lineno); + fprintf(stderr, " expected '%c' (token type) ", it->errtoken); + } else { + cur = in->cur; + lineno = in->lineno; + while (1) { + if (*(cur - 2) == '\r' && *(cur - 1) == '\n') { cur -= 2; --lineno; } + else if (*(cur - 1) == '\n') { --cur; --lineno; } + else { break; } + } + fprintf(stderr, " syntax error - line: %d\n", lineno); + } + + if (!in->nsym) { + cur = in->cur; + lineno = in->lineno; + while (1) { + if (*cur == '\r' && *(cur + 1) == '\n') { cur -= 2; --lineno; } + else if (*cur == '\n') { --cur; --lineno; } + else { break; } + } + fprintf(stderr, " unexpected character '%c' (line: %d)\n", *cur, lineno); + } else { + fprintf(stderr, " got '%c' (token type)\n", in->sym[0].token); + } +} + + +void lex_comment(Input *in) { + size_t n; + int comment_lvl = 1; + + while (1) { + in->sp = in->cur; + /*!use:re2c + NOT_SLASH_STAR = [][!"#$%&'()+,\-.:;<=>?@\\^`{|}~0-9A-Z_a-z ] ; + + "*"+ "/" { + if (!--comment_lvl) { break; } + else { continue; } + } + "*"+ { continue; } + NOT_SLASH_STAR+ { continue; } + "/" { continue; } + "/*" { ++comment_lvl; continue; } */ + } + + return; + +err: + fprintf(stderr, "invalid character in comment, exiting\n"); + exit(1); +} + +#define recover(in, ...) GET_MACRO(__VA_ARGS__, _4, _RECOVER3, _RECOVER2, _RECOVER1)(in, __VA_ARGS__) +#define _RECOVER1(in, u0) _recover((in), (u0), 0U, 0U) +#define _RECOVER2(in, u0, u1) _recover((in), (u0), (u1), 0U) +#define _RECOVER3(in, u0, u1, u2) _recover((in), (u0), (u1), (u2)) + +void _recover(Input *in, uint8_t u0, uint8_t u1, uint8_t u2) { + size_t n; + Symbol sym; + + while (in->nsym) { + if (LOOKAHEAD(in->sym[0], u0, u1, u2, T_EOF)) + break; + --in->nsym; + memmove(&in->sym[0], &in->sym[1], in->nsym * sizeof in->sym[0]); + memset(&in->sym[in->nsym], 0, sizeof in->sym[0]); + } + + if (in->nsym) + return; + + while (1) { + in->sp = in->cur; + /*!use:re2c + P21_START { sym = (Symbol){T_P21_START}; goto check; } + P21_END { sym = (Symbol){T_P21_END}; goto check; } + HEADER { sym = (Symbol){T_HEADER}; goto check; } + DATA / PUNCTUATION { sym = (Symbol){T_DATA}; goto check; } + ENDSEC { sym = (Symbol){T_ENDSEC}; goto check; } + EID { sym = (Symbol){T_EID}; goto check; } + KEYWORD { sym = (Symbol){T_KEYWORD}; goto check; } + REAL { sym = (Symbol){T_VARIANT, V_REAL}; goto check; } + INTEGER { sym = (Symbol){T_VARIANT, V_INTEGER}; goto check; } + STRING { sym = (Symbol){T_VARIANT, V_STRING}; goto check; } + BINARY { sym = (Symbol){T_VARIANT, V_BINARY}; goto check; } + ENUMERATION { sym = (Symbol){T_VARIANT, V_ENUMERATION}; goto check; } + "*" { sym = (Symbol){T_VARIANT, V_DERIVED}; goto check; } + "$" { sym = (Symbol){T_VARIANT, V_EMPTY}; goto check; } + [();] { sym = (Symbol){*in->sp}; goto check; } + */ +check: + if (LOOKAHEAD(sym, u0, u1, u2, T_EOF)) { + PUSH_SYMBOL(sym.token, sym.vtype); + break; + } + } + + return; + +err: + fprintf(stderr, "fatal, failed to resolve follow set (%c, %c, %c)\n", u0, u1, u2); + exit(1); +} + + +/* + * P21Parser + */ +void p21_parse(P21Parser *p, P21ParserActions *act) { + if (act->ud_init_cb) + act->ud_init_cb(act->userdata); + + p21_exchange_file(p, act); + + if (act->ud_exit_cb) + act->ud_exit_cb(act->userdata); + + assert(p->stack->idx_top == 1); + return; + +err: + report_error(p, "exchange_file' << 0 >>\n"); +} + +void p21_exchange_file(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c + P21_START { PUSH_SYMBOL(T_P21_START); continue;} */ + } + PUSH_TERMINAL(p->stack, lpop(in, T_P21_START)); + + p21_header_section(p, act); + p21_data_section_list(p, act); + + PUSH_TERMINAL(p->stack, lpop(in, T_P21_END)); + + if (p->error) + goto err; + + /* user action */ + if (act->exchange_file_cb) + act->exchange_file_cb(p, bsp, act->userdata); + + /* default reduction */ + p->stack->items[bsp] = (Symbol){P_FILE}; + drop(p->stack, p->stack->idx_top - bsp - 1); + + return; + +err: + report_error(p, "exchange_file << 1 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_FILE); + else default_error_handler(p, bsp, P_FILE); + recover(in, T_EOF); +} + +void p21_header_section(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c re2c:labelprefix = 'yya'; + HEADER { PUSH_SYMBOL(T_HEADER); continue; } */ + } + PUSH_TERMINAL(p->stack, lpop(in, T_HEADER)); + + /* section callback */ + if (act->header_start_cb) + act->header_start_cb(p, bsp, act->userdata); + + /* mandatory headers */ + p21_header_entity(p, act); + p21_header_entity(p, act); + p21_header_entity(p, act); + + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c re2c:labelprefix = 'yyb'; + ENDSEC { PUSH_SYMBOL(T_ENDSEC); continue; } + KEYWORD { PUSH_SYMBOL(T_KEYWORD); continue; } */ + } + + /* optional headers */ + if (LOOKAHEAD(in->sym[0], T_KEYWORD)) + p21_header_entity_list(p, act); + + PUSH_TERMINAL(p->stack, lpop(in, T_ENDSEC)); + + if (p->error) + goto err; + + /* default reduction */ + p->stack->items[bsp] = (Symbol){P_HEADERSECTION}; + drop(p->stack, p->stack->idx_top - bsp - 1); + + return; + +err: + report_error(p, "header_section << 2 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_HEADERSECTION); + else default_error_handler(p, bsp, P_HEADERSECTION); + recover(in, T_DATA); +} + +void p21_data_section_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + uint32_t len = 0; + Input *in = p->in; + + do { + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c + DATA / PUNCTUATION { PUSH_SYMBOL(T_DATA); continue; } + P21_END { PUSH_SYMBOL(T_P21_END); continue; } */ + } + if (!LOOKAHEAD(in->sym[0], T_DATA)) + break; + p21_data_section(p, act); + } while (++len); + + /* one or more */ + if (!len) { + push(p->stack, (Symbol){T_ERROR, T_DATA, 0, in->sym[0].lineno}); + p->error = true; + } + + if(p->error) + goto err; + + /* user action */ + if (act->data_section_list_cb) + act->data_section_list_cb(p, bsp, act->userdata); + + /* default reduction */ + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + + return; + +err: + report_error(p, "data_section_list << 3 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, T_P21_END); +} + +void p21_data_section(P21Parser *p, P21ParserActions *act) { + size_t n, cxt; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 2) { + in->sp = in->cur; + /*!use:re2c re2c:labelprefix = 'yya'; + [(;] { PUSH_SYMBOL(*in->sp); continue; } */ + } + PUSH_TERMINAL(p->stack, lpop(in, T_DATA)); + + if (LOOKAHEAD(in->sym[0], '(')) { + PUSH_TERMINAL(p->stack, lpop(in, '(')); + + p21_parameter_list(p, act); + while (in->nsym < 2) { + in->sp = in->cur; + /*!use:re2c re2c:labelprefix = 'yyb'; + ";" { PUSH_SYMBOL(';'); continue; } */ + } + + PUSH_TERMINAL(p->stack, lpop(in, ')')); + } + PUSH_TERMINAL(p->stack, lpop(in, ';')); + + if (act->data_start_cb) + act->data_start_cb(p, bsp, act->userdata); + + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c re2c:labelprefix = 'yyc'; + ENDSEC { PUSH_SYMBOL(T_ENDSEC); continue; } + EID { PUSH_SYMBOL(T_EID); continue; } */ + } + if (LOOKAHEAD(in->sym[0], T_EID)) + p21_entity_instance_list(p, act); + + PUSH_TERMINAL(p->stack, lpop(in, T_ENDSEC)); + + if (p->error) + goto err; + + /* default reduction */ + p->stack->items[bsp] = (Symbol){P_DATASECTION}; + drop(p->stack, p->stack->idx_top - bsp - 1); + + return; + +err: + report_error(p, "data_section << 4 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_DATASECTION); + else default_error_handler(p, bsp, P_DATASECTION); + recover(in, T_P21_END, T_DATA); +} + +void p21_header_entity(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + /* set KEYWORD as basemrk to prevent fill() recycling the buffer before user action */ + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c + KEYWORD { PUSH_SYMBOL(T_KEYWORD); continue; } */ + } + + /* set KEYWORD as basemrk to prevent fill() recycling the buffer before user action */ + assert(in->nsym == 1); + in->basemrk += in->sym[0].offset; + in->sym[0].offset = 0; + + p21_simple_record(p, act); + + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c + ";" { PUSH_SYMBOL(';'); continue; } */ + } + PUSH_TERMINAL(p->stack, lpop(in, ';')); + + if (p->error) + goto err; + + /* user action */ + if (act->header_entity_cb) + act->header_entity_cb(p, bsp, act->userdata); + + /* reduction */ + assert(!p->hold); + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_HEADERENTITY}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "header_entity << 5 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_HEADERENTITY); + else default_error_handler(p, bsp, P_HEADERENTITY); + recover(in, T_ENDSEC, T_KEYWORD); +} + +void p21_header_entity_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + p21_header_entity(p, act); + + do { + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c + KEYWORD { PUSH_SYMBOL(T_KEYWORD); continue; } + ENDSEC { PUSH_SYMBOL(T_ENDSEC); continue; } */ + } + if (!LOOKAHEAD(in->sym[0], T_KEYWORD)) + break; + p21_header_entity(p, act); + } while (1); + + if (p->error) + goto err; + + + /* user action */ + if (act->header_entity_list_cb) + act->header_entity_list_cb(p, bsp, act->userdata); + + /* reduction */ + assert(!p->hold); + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "header_entity_list << 6 >>"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, T_ENDSEC); +} + +void p21_entity_instance_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + p21_entity_instance(p, act); + + do { + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c + EID { PUSH_SYMBOL(T_EID); continue; } + ENDSEC { PUSH_SYMBOL(T_ENDSEC); continue; } */ + } + if (!LOOKAHEAD(in->sym[0], T_EID)) + break; + p21_entity_instance(p, act); + } while (1); + + if (p->error) + goto err; + + /* user action */ + if (act->entity_instance_list_cb) + act->entity_instance_list_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "entity_instance_list << 7 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, T_ENDSEC); +} + +void p21_parameter_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + p21_parameter(p, act); + + do { + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c + [,)] { PUSH_SYMBOL(*in->sp); continue; } */ + } + if (LOOKAHEAD(in->sym[0], ')')) + break; + + PUSH_TERMINAL(p->stack, lpop(in, ',')); + p21_parameter(p, act); + } while (1); + + if (p->error) + goto err; + + /* user action */ + if (act->parameter_list_cb) + act->parameter_list_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "parameter_list << 8 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, ')', ';'); +} + +void p21_entity_instance(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + /* set EID as basemrk to prevent fill() recycling the buffer before user action */ + assert(in->nsym == 1); + in->basemrk += in->sym[0].offset; + in->sym[0].offset = 0; + + while (in->nsym < 3) { + in->sp = in->cur; + /*!use:re2c + KEYWORD { PUSH_SYMBOL(T_KEYWORD); continue; } + [(=] { PUSH_SYMBOL(*in->sp); continue; } */ + } + if (!LOOKAHEAD(in->sym[0], T_EID) || !LOOKAHEAD(in->sym[1], '=')) + goto err; + + if (LOOKAHEAD(in->sym[2], T_KEYWORD)) { + p21_simple_entity_instance(p, act); + } else if (LOOKAHEAD(in->sym[2], '(')) { + p21_complex_entity_instance(p, act); + } + + if (p->error) + goto err; + + /* user action */ + if (act->entity_instance_cb) + act->entity_instance_cb(p, bsp, act->userdata); + + /* no default reduction */ + + return; + +err: + report_error(p, "entity_instance << 9 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, T_ENDSEC, T_EID); +} + +void p21_simple_entity_instance(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + PUSH_TERMINAL(p->stack, lpop(in, T_EID)); + PUSH_TERMINAL(p->stack, lpop(in, '=')); + + p21_simple_record(p, act); + + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c + ";" { PUSH_SYMBOL(';'); continue; } */ + } + PUSH_TERMINAL(p->stack, lpop(in, ';')); + + if (p->error) + goto err; + + /* user action */ + if (act->simple_entity_instance_cb) + act->simple_entity_instance_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_SIMPLEENTITY}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "simple_entity_instance << 10 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_SIMPLEENTITY); + else default_error_handler(p, bsp, P_SIMPLEENTITY); + recover(in, T_ENDSEC, T_EID); +} + + +void p21_complex_entity_instance(P21Parser *p, P21ParserActions *act) { + size_t n, c; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + PUSH_TERMINAL(p->stack, lpop(in, T_EID)); + PUSH_TERMINAL(p->stack, lpop(in, '=')); + PUSH_TERMINAL_EXT(c, p->stack, lpop(in, '(')); + + p21_simple_record_list(p, act); + + while (in->nsym < 2) { + in->sp = in->cur; + /*!use:re2c + ";" { PUSH_SYMBOL(';'); continue; } */ + } + + PUSH_TERMINAL_EXT(c, p->stack, lpop(in, ')')); + PUSH_TERMINAL(p->stack, lpop(in, ';')); + + if (p->error) + goto err; + + /* user action */ + if (act->complex_entity_instance_cb) + act->complex_entity_instance_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_COMPLEXENTITY}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "complex_entity_instance << 11 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_COMPLEXENTITY); + else default_error_handler(p, bsp, P_COMPLEXENTITY); + recover(in, T_ENDSEC, T_EID); +} + +void p21_simple_record(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 3) { + in->sp = in->cur; + /*!use:re2c + KEYWORD { PUSH_SYMBOL(T_KEYWORD); continue; } + REAL { PUSH_SYMBOL(T_VARIANT, V_REAL); continue; } + INTEGER { PUSH_SYMBOL(T_VARIANT, V_INTEGER); continue; } + STRING { PUSH_SYMBOL(T_VARIANT, V_STRING); continue; } + BINARY { PUSH_SYMBOL(T_VARIANT, V_BINARY); continue; } + ENUMERATION { PUSH_SYMBOL(T_VARIANT, V_ENUMERATION); continue; } + EID { PUSH_SYMBOL(T_VARIANT, V_EID); continue; } + "*" { PUSH_SYMBOL(T_VARIANT, V_DERIVED); continue; } + "$" { PUSH_SYMBOL(T_VARIANT, V_EMPTY); continue; } + [()] { PUSH_SYMBOL(*in->sp); continue; } */ + } + + PUSH_TERMINAL(p->stack, lpop(in, T_KEYWORD)); + PUSH_TERMINAL_EXT(n, p->stack, lpop(in, '(')); + + if (LOOKAHEAD(in->sym[0], '(', T_KEYWORD, T_VARIANT)) + p21_parameter_list(p, act); + + PUSH_TERMINAL_EXT(n, p->stack, lpop(in, ')')); + + if (p->error) + goto err; + + /* user action */ + if (act->simple_record_cb) + act->simple_record_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_SIMPLERECORD}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "simple_record << 12 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_SIMPLERECORD); + else default_error_handler(p, bsp, P_SIMPLERECORD); + recover(in, ';', ')', T_KEYWORD); +} + +void p21_simple_record_list(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + p21_simple_record(p, act); + + do { + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c + KEYWORD { PUSH_SYMBOL(T_KEYWORD); continue; } + ")" { PUSH_SYMBOL(')'); continue; } */ + } + if (!LOOKAHEAD(in->sym[0], T_KEYWORD)) + break; + p21_simple_record(p, act); + } while (1); + + if (p->error) + goto err; + + /* user action */ + if (act->simple_record_list_cb) + act->simple_record_list_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_LIST}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "simple_record_list << 13 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_LIST); + else default_error_handler(p, bsp, P_LIST); + recover(in, ')', ';'); +} + +void p21_parameter(P21Parser *p, P21ParserActions *act) { + size_t n; + uint32_t bsp = p->stack->idx_top; + Input *in = p->in; + + while (in->nsym < 2) { + in->sp = in->cur; + /*!use:re2c re2c:labelprefix='yya'; + KEYWORD { PUSH_SYMBOL(T_KEYWORD); continue; } + REAL { PUSH_SYMBOL(T_VARIANT, V_REAL); continue; } + INTEGER { PUSH_SYMBOL(T_VARIANT, V_INTEGER); continue; } + STRING { PUSH_SYMBOL(T_VARIANT, V_STRING); continue; } + BINARY { PUSH_SYMBOL(T_VARIANT, V_BINARY); continue; } + ENUMERATION { PUSH_SYMBOL(T_VARIANT, V_ENUMERATION); continue; } + EID { PUSH_SYMBOL(T_VARIANT, V_EID); continue; } + "*" { PUSH_SYMBOL(T_VARIANT, V_DERIVED); continue; } + "$" { PUSH_SYMBOL(T_VARIANT, V_EMPTY); continue; } + [(),] { PUSH_SYMBOL(*in->sp); continue; } */ + } + + if (LOOKAHEAD(in->sym[0], T_VARIANT)) { + PUSH_TERMINAL(p->stack, lpop(in, T_VARIANT)); + } else { + if (LOOKAHEAD(in->sym[0], T_KEYWORD)) { + PUSH_TERMINAL(p->stack, lpop(in, T_KEYWORD)); + PUSH_TERMINAL(p->stack, lpop(in, '(')); + p21_parameter(p, act); + } else { + PUSH_TERMINAL(p->stack, lpop(in, '(')); + if (LOOKAHEAD(in->sym[0], '(', T_KEYWORD, T_VARIANT)) { + p21_parameter_list(p, act); + } + } + while (in->nsym < 1) { + in->sp = in->cur; + /*!use:re2c re2c:labelprefix='yyb'; + ")" { PUSH_SYMBOL(')'); continue; } */ + } + PUSH_TERMINAL(p->stack, lpop(in, ')')); + } + + if (p->error) + goto err; + + /* user action */ + if (act->parameter_cb) + act->parameter_cb(p, bsp, act->userdata); + + /* reduction */ + if (!p->hold) { + p->stack->items[bsp] = (Symbol){P_PARAMETER}; + drop(p->stack, p->stack->idx_top - bsp - 1); + } + + return; + +err: + report_error(p, "parameter << 14 >>\n"); + if (act->error_cb) act->error_cb(p, bsp, P_PARAMETER); + else default_error_handler(p, bsp, P_PARAMETER); + recover(in, ')', ',', ';'); +} + +void mock_error(P21Parser *, int, uint8_t); +void mock_ud_init(void *); +void mock_ud_exit(void *); +void mock_exchange_file(P21Parser *, int, void *); +void mock_header_start(P21Parser *, int, void *); +void mock_header_entity_list(P21Parser *, int, void *); +void mock_data_section_list(P21Parser *, int, void *); +void mock_data_start(P21Parser *, int, void *); +void mock_header_entity(P21Parser *, int, void *); +void mock_simple_entity_instance(P21Parser *, int, void *); +void mock_complex_entity_instance(P21Parser *, int, void *); +void mock_parameter_list(P21Parser *, int, void *); +void mock_parameter(P21Parser *, int, void *); +void mock_entity_instance_list(P21Parser *, int, void *); +void mock_entity_instance(P21Parser *, int, void *); +void mock_simple_record_list(P21Parser *, int, void *); +void mock_simple_record(P21Parser *, int, void *); +void mock_noop(P21Parser *, int, void *); + +typedef struct { + sqlite3 *db; + sqlite3_stmt *sec_stmt; + sqlite3_stmt *sei_stmt; + sqlite3_stmt *cei_stmt; + sqlite3_stmt *hei_stmt; + int section_idx; +} P21UserData; + +P21UserData mockdata = {0}; + +P21ParserActions mockact = { + .userdata = &mockdata, + .error_cb = mock_error, + .ud_init_cb = mock_ud_init, + .ud_exit_cb = mock_ud_exit, + .header_start_cb = mock_header_start, + .data_start_cb = mock_data_start, + .exchange_file_cb = NULL, + .header_entity_list_cb = NULL, + .data_section_list_cb = NULL, + .header_entity_cb = mock_header_entity, + .simple_entity_instance_cb = mock_simple_entity_instance, + .complex_entity_instance_cb = mock_complex_entity_instance, + .parameter_list_cb = mock_noop, + .parameter_cb = mock_noop, + .entity_instance_list_cb = NULL, + .entity_instance_cb = NULL, + .simple_record_list_cb = mock_noop, + .simple_record_cb = mock_noop +}; + +void mock_error(P21Parser *p, int bsp, uint8_t cxt) { + switch (cxt) { + case P_SIMPLEENTITY: + case P_COMPLEXENTITY: + case P_HEADERENTITY: + dprintf("caught error: '%c'\n", cxt); + p->error = false; + drop(p->stack, p->stack->idx_top - bsp - 1); + break; + default: + p->error = true; + break; + } +} + + +void mock_ud_init(void *d) { + P21UserData *ud = d; + char ddl_sql[] = + "PRAGMA foreign_keys = ON;\n" + "CREATE TABLE entity_enum (type TEXT(1) PRIMARY KEY);\n" + "INSERT INTO entity_enum (type) VALUES ('S'), ('C');\n" + "CREATE TABLE section_enum (type TEXT(1) PRIMARY KEY);\n" + "INSERT INTO section_enum (type) VALUES ('D'), ('H');\n" + + "CREATE TABLE section_table (\n" + " id INTEGER PRIMARY KEY,\n" + " lineno INTEGER NOT NULL,\n" + " section_type TEXT(1) NOT NULL REFERENCES section_enum(type)\n" + ");\n" + + "CREATE TABLE section_headers (\n" + " id INTEGER PRIMARY KEY,\n" + " type_name TEXT COLLATE NOCASE,\n" + " raw_data TEXT NOT NULL,\n" + " lineno INTEGER NOT NULL,\n" + " fk_section INTEGER NOT NULL REFERENCES section_table(id)\n" + ");\n" + + "CREATE TABLE data_table (\n" + " id TEXT PRIMARY KEY,\n" + " type_name TEXT COLLATE NOCASE,\n" + " raw_data TEXT NOT NULL,\n" + " lineno INTEGER NOT NULL,\n" + " entity_type TEXT(1) NOT NULL REFERENCES entity_enum(type),\n" + " fk_section INTEGER NOT NULL REFERENCES section_table(id)\n" + ") WITHOUT ROWID;\n" + + "BEGIN DEFERRED TRANSACTION;"; + + char sei_sql[] = "INSERT INTO data_table VALUES (?,?,?,?,'S',?)"; + char cei_sql[] = "INSERT INTO data_table VALUES (?,NULL,?,?,'C',?)"; + char hei_sql[] = "INSERT INTO section_headers(type_name, raw_data, lineno, fk_section) VALUES (?, ?, ?, ?)"; + int rc; + + rc = sqlite3_open_v2(":memory:", &ud->db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); + + /* TODO: read ddl sql from external file */ + rc = sqlite3_exec(ud->db, ddl_sql, NULL, NULL, NULL); + + rc |= sqlite3_prepare_v3(ud->db, sei_sql, sizeof sei_sql, SQLITE_PREPARE_PERSISTENT, &ud->sei_stmt, NULL); + rc |= sqlite3_prepare_v3(ud->db, cei_sql, sizeof cei_sql, SQLITE_PREPARE_PERSISTENT, &ud->cei_stmt, NULL); + rc |= sqlite3_prepare_v3(ud->db, hei_sql, sizeof hei_sql, SQLITE_PREPARE_PERSISTENT, &ud->hei_stmt, NULL); + + if (rc != SQLITE_OK) + exit(1); + + ud->section_idx = 0; +} + +void mock_ud_exit(void *d) { + P21UserData *ud = d; + int rc; + char ddl_sql[] = + "CREATE INDEX ix_type_name ON data_table(type_name);\n" + "CREATE INDEX ix_entity_type ON data_table(entity_type);\n" + "CREATE INDEX ix_fk_section ON data_table(fk_section);"; + + rc = sqlite3_finalize(ud->sei_stmt); + rc |= sqlite3_finalize(ud->cei_stmt); + rc |= sqlite3_finalize(ud->hei_stmt); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_exec(ud->db, "COMMIT TRANSACTION", NULL, NULL, NULL); + if (rc != SQLITE_OK) goto err; + + /* TODO: benchmark index creation here vs on db init */ + rc = sqlite3_exec(ud->db, ddl_sql, NULL, NULL, NULL); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_close(ud->db); + if (rc != SQLITE_OK) goto err; + + return; +err: + dprintf("db error\n"); + exit(1); +} + +void mock_exchange_file(P21Parser *p, int bsp, void *d) { Stack *s = p->stack; } +void mock_header_start(P21Parser *p, int bsp, void *d) { + char sec_sql[] = "INSERT INTO section_table VALUES(?,?,'H')"; + Stack *s = p->stack; + P21UserData *ud = d; + Symbol *t = s->items + bsp; + sqlite3_stmt *stmt; + int rc; + + rc = sqlite3_prepare_v2(ud->db, sec_sql, sizeof sec_sql, &stmt, NULL); + if (rc != SQLITE_OK) goto err; + + rc |= sqlite3_bind_int(stmt, 1, ++ud->section_idx); + rc |= sqlite3_bind_int(stmt, 2, t->lineno); + if (rc != SQLITE_OK) goto err; + + rc |= sqlite3_step(stmt); + if (rc != SQLITE_DONE) goto err; + + sqlite3_finalize(stmt); + + /* + s->items[bsp] = (Symbol){P_HEADERSECTION}; + drop(s, s->idx_top - bsp - 1); + */ + + return; + +err: + dprintf("db error\n"); + exit(1); +} +void mock_header_entity_list(P21Parser *p, int bsp, void *d) { Stack *s = p->stack; } +void mock_data_section_list(P21Parser *p, int bsp, void *d) { Stack *s = p->stack; } +void mock_data_start(P21Parser *p, int bsp, void *d) { + char sec_sql[] = "INSERT INTO section_table VALUES(?,?,'D')"; + Stack *s = p->stack; + P21UserData *ud = d; + Symbol *t = s->items + bsp; + sqlite3_stmt *stmt; + int rc; + + rc = sqlite3_prepare_v2(ud->db, sec_sql, sizeof sec_sql, &stmt, NULL); + if (rc != SQLITE_OK) goto err; + + rc |= sqlite3_bind_int(stmt, 1, ++ud->section_idx); + rc |= sqlite3_bind_int(stmt, 2, t->lineno); + if (rc != SQLITE_OK) goto err; + + rc |= sqlite3_step(stmt); + if (rc!= SQLITE_DONE) goto err; + + sqlite3_finalize(stmt); + + return; + +err: + dprintf("db error\n"); + exit(1); +} + +void mock_header_entity(P21Parser *p, int bsp, void *d) { + Stack *s = p->stack; + P21UserData *ud = d; + HeaderEntity e = {s->items + bsp, s->items + bsp + 1}; + size_t i, nargs = e.args->n; + unsigned char *basemrk = p->in->basemrk; + ptrdiff_t ep; + int rc; + + /* rewrite (normalise) args member before bind */ + e.args->offset = (e.args + 1)->offset; + e.args->n = (e.args + 1)->n; + for (i = 2, ep = e.args->offset + 1; i < nargs; i++) { + Symbol *t = e.args + i; + if (t->token == '(') t->n = 1; + if (ep != t->offset) memmove(basemrk + ep, basemrk + t->offset, t->n); + ep += t->n; + } + e.args->n = ep - e.args->offset; + + rc = sqlite3_reset(ud->hei_stmt); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_bind_text(ud->hei_stmt, 1, basemrk + e.kw->offset, e.kw->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_text(ud->hei_stmt, 2, basemrk + e.args->offset, e.args->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_int(ud->hei_stmt, 3, e.kw->lineno); + rc |= sqlite3_bind_int(ud->hei_stmt, 4, ud->section_idx); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_step(ud->hei_stmt); + if (rc != SQLITE_DONE) goto err; + + p->hold = false; + return; + +err: + mock_error(p, bsp, P_HEADERENTITY); + dprintf("db error\n"); +} + +void mock_simple_entity_instance(P21Parser *p, int bsp, void *d) { + Stack *s = p->stack; + P21UserData *ud = d; + SimpleEntity e = {s->items + bsp, s->items + bsp + 1, s->items + bsp + 2, s->items + bsp + 3}; + size_t i, nargs = e.args->n; + unsigned char *basemrk = p->in->basemrk; + ptrdiff_t ep; + int rc; + + /* rewrite (normalise) args before bind */ + e.args->offset = (e.args + 1)->offset; + e.args->n = (e.args + 1)->n; + for (i = 2, ep = e.args->offset + e.args->n; i < nargs; i++) { + Symbol *t = e.args + i; + if (t->token == '(') t->n = 1; + if (ep != t->offset) memmove(basemrk + ep, basemrk + t->offset, t->n); + ep += t->n; + } + e.args->n = ep - e.args->offset; + + /* */ + rc = sqlite3_reset(ud->sei_stmt); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_bind_text(ud->sei_stmt, 1, basemrk + e.eid->offset, e.eid->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_text(ud->sei_stmt, 2, basemrk + e.kw->offset, e.kw->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_text(ud->sei_stmt, 3, basemrk + e.args->offset, e.args->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_int(ud->sei_stmt, 4, e.eid->lineno); + rc |= sqlite3_bind_int(ud->sei_stmt, 5, ud->section_idx); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_step(ud->sei_stmt); + if (rc != SQLITE_DONE) goto err; + + p->hold = false; + + return; + +err: + mock_error(p, bsp, P_SIMPLEENTITY); + dprintf("db error\n"); +} + + +void mock_complex_entity_instance(P21Parser *p, int bsp, void *d) { + Stack *s = p->stack; + P21UserData *ud = d; + ComplexEntity e = {s->items + bsp, s->items + bsp + 1, s->items + bsp + 2}; + size_t i, nsubsupers = e.subsupers->n; + unsigned char *basemrk = p->in->basemrk; + ptrdiff_t ep; + int rc; + + /* rewrite (normalise) list before bind */ + for (i = 1, ep = e.subsupers->offset + 1; i < nsubsupers; i++) { + Symbol *t = e.subsupers + i; + if (t->token == '(') t->n = 1; + if (ep != t->offset) memmove(basemrk + ep, basemrk + t->offset, t->n); + ep += t->n; + } + e.subsupers->n = ep - e.subsupers->offset; + + rc = sqlite3_reset(ud->cei_stmt); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_bind_text(ud->cei_stmt, 1, basemrk + e.eid->offset, e.eid->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_text(ud->cei_stmt, 2, basemrk + e.subsupers->offset, e.subsupers->n, SQLITE_TRANSIENT); + rc |= sqlite3_bind_int(ud->cei_stmt, 3, e.eid->lineno); + rc |= sqlite3_bind_int(ud->cei_stmt, 4, ud->section_idx); + if (rc != SQLITE_OK) goto err; + + rc = sqlite3_step(ud->cei_stmt); + if (rc != SQLITE_DONE) goto err; + + p->hold = false; + return; + +err: + mock_error(p, bsp, P_COMPLEXENTITY); + dprintf("db error \n"); +} + +void mock_parameter_list(P21Parser *p, int bsp, void *d) { } +void mock_parameter(P21Parser *p, int bsp, void *d) { } +void mock_entity_instance_list(P21Parser *p, int bsp, void *d) { } +void mock_entity_instance(P21Parser *p, int bsp, void *d) { } +void mock_simple_record_list(P21Parser *p, int bsp, void *d) { } +void mock_simple_record(P21Parser *p, int bsp, void *d) {} + +void mock_noop(P21Parser *p, int bsp, void *d) { + p->hold = true; +} + +int main(char *argv[], int argc) { + const char *paths[] = { + "/home/chorler/projects/src/stepcode/test/p21/test_array_bounds_FAIL1.p21", + "/home/chorler/projects/src/stepcode/test/p21/comments.p21", + "/home/chorler/projects/src/stepcode/test/p21/test_inverse_attr.p21", + "/home/chorler/projects/src/stepcode/test/p21/missing_and_required.p21", + "/home/chorler/projects/src/stepcode/test/p21/test_array_bounds.p21", + "/home/chorler/projects/src/stepcode/test/p21/test_inherit_inverse.p21", + "/home/chorler/projects/src/stepcode/data/ap214e3/as1-oc-214.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/dm1-id-214.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/MAINBODY.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/HEAD_BACK.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/HEAD_FRONT.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/TAIL.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/MAINBODY_FRONT.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/FOOT_BACK_000.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/FOOT_FRONT_000.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/s1-c5-214.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/MAINBODY_BACK.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/HEAD.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/TAIL_TURBINE.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/TAIL_MIDDLE_PART.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/s1-c5-214/FOOT.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/sg1-c5-214.stp", + "/home/chorler/projects/src/stepcode/data/ap214e3/io1-cm-214.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS7-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS1Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS2-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS1Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS3-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS10Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS2Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS8-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS3Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS4Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS7Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS4Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS10Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS3Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS8Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS4-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS7Mod0-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS2Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS8Mod0-outresult.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS10-out.stp", + "/home/chorler/projects/src/stepcode/data/ap209/ATS1-out.stp" + }; + + P21Parser myp; + P21UserData mydata; + FILE *fp; + memset(&mydata, 0, sizeof mydata); + + for (unsigned int i = 0; i < (sizeof paths / sizeof paths[0]); i++) { + fp = fopen(paths[i], "rb"); + if (!fp) { fprintf(stderr, "failed to read input: %s\n", paths[i]); continue; } + else { fprintf(stderr, "processing: %s\n", paths[i]); } + p21_init(&myp, fp); + p21_parse(&myp, &mockact); + } +} diff --git a/src/exp2python/python/stepcode/cPart21.py b/src/exp2python/python/stepcode/cPart21.py new file mode 100644 index 000000000..6e4b9a697 --- /dev/null +++ b/src/exp2python/python/stepcode/cPart21.py @@ -0,0 +1,586 @@ +# +# STEP Part 21 Parser +# +# Copyright (c) 2020, Christopher HORLER (cshorler@googlemail.com) +# +# All rights reserved. +# +# This file is part of the STEPCODE project. +# +# 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. +# +# Neither the name of the nor the names of its contributors may +# be used to endorse or promote products derived from this software without +# specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import logging +import os.path, sqlite3, datetime, tempfile + +import re +import ply.lex as lex +import ply.yacc as yacc +from ply.lex import LexError, TOKEN + +logger = logging.getLogger(__name__) +#logger.addHandler(logging.NullHandler()) + +# assemble catchall regexp +p21_real = r'(?:[+-]*[0-9][0-9]*\.[0-9]*(?:E[+-]*[0-9][0-9]*)?)' +p21_integer = r'(?:[+-]*[0-9][0-9]*)' +p21_string = r"""(?x)(?:' + (?: + # basic string + [][!"*$%&.#+,\-()?/:;<=>@{}|^`~0-9a-zA-Z_ ]|''|\\\\| + # \P\A, \P\B, ... --> iso8859-1, iso8859-2,... applicable to following \S\c directives + \\P[A-I]\\| + # page control directive \S\c + \\S\\[][!"'*$%&.#+,\-()?/:;<=>@{}|^`~0-9a-zA-Z_\\ ]| + # hex string encodings + \\X2\\(?:[0-9A-F]{4})+\\X0\\|\\X4\\(?:[0-9A-F]{8})+\\X0\\| + # hex byte encoding + \\X\\[0-9A-F]{2} + )* +')""" +p21_binary = r'(?:"[0-3][0-9A-F]*")' +p21_enumeration = r'(?:\.[A-Z_][A-Z0-9_]*\.)' +p21_keyword = r'(?:!|)[A-Za-z_][0-9A-Za-z_]*' +p21_eid = r'\#[0-9]+' + +_catchall_types = [p21_real, p21_integer, p21_string, p21_binary, p21_enumeration, + p21_keyword, p21_eid] + +groups_re = re.compile(r"(?P\()|(?P\#[0-9]+)|(?P\))|(?P')") +p21_string_re = re.compile(p21_string) + +def _mkgroups(s): + """used to populate the xref database table""" + stack_idx = 0 + stack_depth = 2 + stack = [set(), set()] + + cp = 0 + while True: + m = groups_re.search(s, cp) + if not m: break + + if m.group('eid'): + stack[stack_idx].add(m.group()) + elif m.group('lparens'): + stack_idx += 1 + if stack_idx == len(stack): + stack_depth += 2 + stack.extend((set(), set())) + elif m.group('rparens'): + stack_idx -= 1 + else: + m = p21_string_re.match(s, m.start()) + + cp = m.end() + + groups = [] + if any(stack): + _stack = filter(bool, stack) + # expand the first level + stack = tuple((x,) for x in next(_stack)) + tuple(_stack) + groups = list(enumerate(stack, 1)) + + return groups + + +base_tokens = ['PART21_START', 'PART21_END', 'HEADER', 'DATA', 'ENDSEC', + 'INTEGER', 'REAL', 'KEYWORD', 'STRING', 'BINARY', 'ENUMERATION', + 'EID', 'RAW'] + +#################################################################################################### +# Lexer +#################################################################################################### +class Lexer(object): + tokens = list(base_tokens) + literals = '()=;,*$' + + states = (('slurp', 'exclusive'), + ('header', 'exclusive'), + ('data', 'exclusive'), + ('raw', 'exclusive'), + ('params', 'exclusive')) + + def __init__(self, debug=False, optimize=False, header_limit=4096): + self.base_tokens = list(base_tokens) + self.schema_dict = {} + self.active_schema = {} + self.header_limit = header_limit + self.lexer = lex.lex(module=self, debug=debug, optimize=optimize, lextab='cl21tab', + debuglog=logger, errorlog=logger) + self.reset() + + def __getattr__(self, name): + if name == 'lineno': + return self.lexer.lineno + elif name == 'lexpos': + return self.lexer.lexpos + else: + raise AttributeError + + def input(self, s): + self.lexer.input(s) + + def reset(self): + self.lexer.lineno = 1 + self.lexer.lvl = 0 + self.lexer.begin('slurp') + + def token(self): + return self.lexer.token() + + def activate_schema(self, schema_name): + if schema_name in self.schema_dict: + self.active_schema = self.schema_dict[schema_name] + else: + raise ValueError('schema not registered') + + def register_schema(self, schema_name, entities): + if schema_name in self.schema_dict: + raise ValueError('schema already registered') + + for k in entities: + if k in self.base_tokens: raise ValueError('schema cannot override base_tokens') + + if isinstance(entities, list): + entities = dict((k, k) for k in entities) + + self.schema_dict[schema_name] = entities + + def t_slurp_error(self, t): + m = re.search(r'(?P/\*)|(ISO-10303-21;)', t.value[:self.header_limit]) + if m: + if m.group('comment'): + t.lexer.skip(m.start()) + else: + t.type = 'PART21_START' + t.value = m.group() + t.lexpos += m.start() + t.lineno += t.value[:m.start()].count('\n') + t.lexer.lexpos += m.end() + t.lexer.begin('INITIAL') + return t + elif len(t.value) < self.header_limit: + t.lexer.skip(len(t.value)) + else: + raise LexError("Scanning error. try increasing lexer header_limit parameter", + "{0}...".format(t.value[0:20])) + + def t_error(self, t): + raise LexError("Scanning error, invalid input", "{0}...".format(t.value[0:20])) + + def t_ANY_COMMENT(self, t): + r'/\*(?:.|\n)*?\*/' + t.lexer.lineno += t.value.count('\n') + + + def t_PART21_END(self, t): + r'END-ISO-10303-21;' + self.lexer.lvl = 0 + self.lexer.begin('slurp') + return t + def t_HEADER(self, t): + r'HEADER;' + t.lexer.push_state('header') + return t + def t_header_data_ENDSEC(self, t): + r'ENDSEC;' + t.lexer.pop_state() + return t + def t_DATA(self, t): + r'DATA\b' + t.lexer.in_header = True + t.lexer.push_state('data') + return t + + + @TOKEN(p21_keyword) + def t_header_KEYWORD(self, t): + return t + def t_header_lparens(self, t): + r'\(' + t.lexer.lexpos -= 1 + t.lexer.push_state('params') + def t_header_rparens(self, t): + r'\)' + t.type = ')' + t.lexer.pop_state() + return t + + + def t_data_lparens(self, t): + r'\(' + if t.lexer.in_header: + t.type = '(' + t.lexer.push_state('header') + else: + t.type = 'RAW' + t.lexer.push_state('raw') + return t + def t_data_header_end(self, t): + r';' + t.type = ';' + t.lexer.in_header = False + return t + @TOKEN(p21_eid) + def t_data_EID(self, t): + return t + @TOKEN(p21_keyword) + def t_data_KEYWORD(self, t): + t.lexer.push_state('raw') + return t + + + def t_params_lparens(self, t): + r'\(' + t.type = 'RAW' + t.lexer.lvl += 1 + return t + def t_params_rparens(self, t): + r'\)' + t.type = 'RAW' + t.lexer.lvl -= 1 + if t.lexer.lvl == 0: + t.lexer.pop_state() + return t + @TOKEN('(?:' + '|'.join(_catchall_types) + r'|(?:[,*$]))+') + def t_params_RAW(self, t): + return t + + + def t_raw_end(self, t): + r';' + t.lexer.pop_state() + t.type = ';' + return t + @TOKEN('(?:' + '|'.join(_catchall_types) + r'|(?:[(),*$]))+') + def t_raw_RAW(self, t): + return t + + + def t_ANY_newline(self, t): + r'\n+' + t.lexer.lineno += len(t.value) + t_ANY_ignore = ' \t\r' + + +#################################################################################################### +# Parser +#################################################################################################### +class Parser(object): + tokens = list(base_tokens) + + def __init__(self, lexer=None, debug=False, tabmodule=None, start=None, optimize=False, + tempdb=False): + # defaults + start_tabs = {'exchange_file': 'cp21tab', 'extract_header': 'cp21hdrtab'} + if start and tabmodule: start_tabs[start] = tabmodule + if not start: start = 'exchange_file' + if start not in start_tabs: raise ValueError('please pass (dedicated) tabmodule') + + self.tempdb = tempdb + self.lexer = lexer if lexer else Lexer() + self.parser = yacc.yacc(debug=debug, module=self, tabmodule=start_tabs[start], start=start, + optimize=optimize, debuglog=logger, errorlog=logger) + + def parse(self, p21_data, db_path=None, **kwargs): + #TODO: will probably need to change this function if the lexer is ever to support t_eof + self.reset(self.tempdb, db_path) + self.lexer.input(p21_data) + + if 'debug' in kwargs: + result = self.parser.parse(lexer=self.lexer, debug=logger, + ** dict((k, v) for k, v in kwargs.items() if k != 'debug')) + else: + result = self.parser.parse(lexer=self.lexer, **kwargs) + return result + + def reset(self, tempdb=None, db_path=None): + self.lexer.reset() + self.initdb(tempdb, db_path) + + def closedb(self): + try: + self.db_cxn.commit() + self.db_cxn.close() + except AttributeError: + pass + + def initdb(self, tempdb, db_path=None): + if tempdb and not db_path: + tm = datetime.datetime.utcnow().isoformat(timespec='seconds').replace(':','-') + db_path = os.path.join(tempfile.mkdtemp(), tm + '_test.db') + elif not db_path: + db_path = ":memory:" + logger.info('db_path: %s', db_path) + self.db_cxn = sqlite3.connect(db_path) + self.db_writer = self.db_cxn.cursor() + self.db_writer.executescript(""" + PRAGMA foreign_keys = ON; + CREATE TABLE entity_enum (type TEXT(1) PRIMARY KEY); + INSERT INTO entity_enum (type) VALUES ('S'), ('C'); + CREATE TABLE section_enum (type TEXT(1) PRIMARY KEY); + INSERT INTO section_enum (type) VALUES ('D'), ('H'); + + CREATE TABLE section_table ( + id INTEGER PRIMARY KEY, + lineno INTEGER NOT NULL, + section_type TEXT(1) NOT NULL REFERENCES section_enum(type) + ); + + CREATE TABLE section_headers ( + id INTEGER PRIMARY KEY, + type_name TEXT COLLATE NOCASE, + raw_data TEXT NOT NULL, + lineno INTEGER NOT NULL, + fk_section INTEGER NOT NULL REFERENCES section_table(id) + ); + + CREATE TABLE data_table ( + id TEXT PRIMARY KEY, + type_name TEXT COLLATE NOCASE, + raw_data TEXT NOT NULL, + lineno INTEGER NOT NULL, + entity_type TEXT(1) NOT NULL REFERENCES entity_enum(type), + fk_section INTEGER NOT NULL REFERENCES section_table(id) + ) WITHOUT ROWID; + + CREATE TABLE data_xref ( + id_from TEXT NOT NULL REFERENCES data_table(id) DEFERRABLE INITIALLY DEFERRED, + id_to TEXT NOT NULL REFERENCES data_table(id), + id_group INTEGER NOT NULL, + PRIMARY KEY (id_from, id_to, id_group) + ) WITHOUT ROWID; + + CREATE INDEX ix_type_name ON data_table(type_name); + CREATE INDEX ix_entity_type ON data_table(entity_type); + CREATE INDEX ix_fk_section ON data_table(fk_section); + CREATE INDEX ix_id_from ON data_xref(id_from); + """) + self.db_cxn.commit() + + def p_exchange_file(self, p): + """exchange_file : PART21_START header_section data_section_list PART21_END""" + self.closedb() + + def p_header_section(self, p): + """header_section : header_start header_entity header_entity header_entity ENDSEC""" + + def p_header_section_with_entity_list(self, p): + """header_section : header_start header_entity header_entity header_entity header_entity_list ENDSEC""" + + def p_header_section_start(self, p): + """header_start : HEADER""" + tmpl = "INSERT INTO section_table(lineno, section_type) VALUES (?,?)" + self.db_writer.execute(tmpl, (p.lineno(1), 'H')) + self.db_writer.execute('SELECT last_insert_rowid();') + (self.sid,) = self.db_writer.fetchone() + + def p_header_entity(self, p): + """header_entity : KEYWORD raw_data ';'""" + tmpl = "INSERT INTO section_headers(type_name, raw_data, lineno, fk_section) VALUES (?, ?, ?, ?)" + self.db_writer.execute(tmpl, (p[1], p[2], p.lineno(1), self.sid)) + + def p_header_entity_list_init(self, p): + """header_entity_list : header_entity""" + + def p_header_entity_list(self, p): + """header_entity_list : header_entity_list header_entity""" + + def p_data_section(self, p): + """data_section : data_start entity_instance_list ENDSEC""" + + def p_data_start(self, p): + """data_start : DATA '(' parameter_list ')' ';'""" + tmpl = "INSERT INTO section_table(lineno, section_type) VALUES (?,?)" + lineno = p.lineno(1) + self.db_writer.execute(tmpl, (lineno, 'D')) + self.db_writer.execute('SELECT last_insert_rowid();') + (self.sid,) = self.db_writer.fetchone() + tmpl = "INSERT INTO section_headers(type_name, raw_data, lineno, fk_section) VALUES (?, ?, ?, ?)" + self.db_writer.executemany(tmpl, [(t, x, lineno, self.sid) for t, x in p[3]]) + + def p_data_start_empty(self, p): + """data_start : DATA '(' ')' ';' + | DATA ';'""" + tmpl = "INSERT INTO section_table(lineno, section_type) VALUES (?,?)" + self.db_writer.execute(tmpl, (p.lineno(1), 'D')) + self.db_writer.execute('SELECT last_insert_rowid();') + (self.sid,) = self.db_writer.fetchone() + + def p_data_section_list_init(self, p): + """data_section_list : data_section""" + + def p_data_section_list(self, p): + """data_section_list : data_section_list data_section""" + + def p_entity_instance_list_init(self, p): + """entity_instance_list : entity_instance""" + + def p_entity_instance_list(self, p): + """entity_instance_list : entity_instance_list entity_instance""" + + def p_entity_instance(self, p): + """entity_instance : simple_entity_instance + | complex_entity_instance""" + + def p_entity_instance_error(self, p): + """entity_instance : EID '=' error ';'""" + logger.error('resyncing parser, check input between lineno %d and %d', p.lineno(2), p.lineno(4)) + + def p_simple_entity_instance(self, p): + """simple_entity_instance : EID '=' KEYWORD raw_data ';'""" + eid = p[1] + tmpl = "INSERT INTO data_table VALUES (?,?,?,?,?,?)" + self.db_writer.execute(tmpl, (p[1], p[3], p[4][1:-1], p.lineno(1), 'S', self.sid)) + tmpl = "INSERT INTO data_xref(id_from, id_to, id_group) VALUES (?, ?, ?)" + xrefs = [(rid, eid, n) for n, x in _mkgroups(p[4]) for rid in x] + self.db_writer.executemany(tmpl, xrefs) + + def p_complex_entity_instance(self, p): + """complex_entity_instance : EID '=' raw_data ';'""" + eid = p[1] + tmpl = "INSERT INTO data_table VALUES (?,NULL,?,?,?,?)" + self.db_writer.execute(tmpl, (p[1], p[3], p.lineno(1), 'C', self.sid)) + tmpl = "INSERT INTO data_xref(id_from, id_to, id_group) VALUES (?, ?, ?)" + xrefs = [(rid, eid, n) for n, x in _mkgroups(p[3]) for rid in x] + self.db_writer.executemany(tmpl, xrefs) + + def p_parameter_list_init(self, p): + """parameter_list : parameter""" + p[0] = [p[1],] + + def p_parameter_list(self, p): + """parameter_list : parameter_list ',' parameter""" + p[0] = p[1] + p[0].append(p[3]) + + def p_typed_parameter(self, p): + """parameter : KEYWORD raw_data""" + p[0] = (p[1], p[2]) + + def p_other_parameter(self, p): + """parameter : raw_data""" + p[0] = (None, p[1]) + + def p_raw_concat(self, p): + """raw_data : raw_data RAW + | RAW""" + try: p[0] = p[1] + p[2] + except IndexError: p[0] = p[1] + + +def debug_lexer(): + import codecs + from os.path import normpath, expanduser + + logging.basicConfig() + logger.setLevel(logging.DEBUG) + + lexer = Lexer(debug=True) + + p = normpath(expanduser('~/projects/src/stepcode/data/ap214e3/s1-c5-214/s1-c5-214.stp')) + with codecs.open(p, 'r', encoding='iso-8859-1') as f: + s = f.read() + lexer.input(s) + while True: + tok = lexer.token() + if not tok: break + logger.debug(tok) + +def debug_parser(): + import codecs + from os.path import normpath, expanduser + + logging.basicConfig() + logger.setLevel(logging.DEBUG) + + parser = Parser(debug=True, tempdb=True) + + logger.info("***** parser debug *****") + p = normpath(expanduser('~/projects/src/stepcode/data/ap214e3/s1-c5-214/s1-c5-214.stp')) + with codecs.open(p, 'r', encoding='iso-8859-1') as f: + s = f.read() + parser.parse(s, debug=1) + + # test reverse lookup + logger.info('***** testing xrefs *****') + tm = datetime.datetime.utcnow().isoformat(timespec='seconds').replace(':', '-') + db_path = os.path.join(tempfile.mkdtemp(), tm + '_xref_test.db') + + parser = Parser() + + p = normpath(expanduser('~/projects/src/stepcode/data/ap214e3/s1-c5-214/s1-c5-214.stp')) + with codecs.open(p, 'r', encoding='iso-8859-1') as f: + s = f.read() + parser.parse(s, db_path=db_path) + + # contrived use case: we're looking for the objects referencing each of these [set] of items + items = [('#53','#93','#133','#173','#191'), ('#174','#192'), ('#193','#196','#195'), ('#1',)] + tmpl = "SELECT id_to FROM data_xref WHERE id_from IN (%s) GROUP BY id_group, id_to HAVING count(id_to) = ?" + with sqlite3.connect(db_path) as db_cxn: + for grp in items: + db_cursor = db_cxn.execute(tmpl % ','.join('?'*len(grp)), grp + (len(grp),)) + for eid in db_cursor: + logger.info('grp: %s, ref: %r', grp, eid) + + logger.info("***** finished *****") + +def test(): + import os, codecs + from os.path import normpath, expanduser + + logging.basicConfig() + logger.setLevel(logging.INFO) + + lexer = Lexer(optimize=True) + parser = Parser(lexer=lexer, optimize=True) + + def parse_check(p): + logger.info("processing {0}".format(p)) + parser.reset() + with codecs.open(p, 'r', encoding='iso-8859-1') as f: + s = f.read() + parser.parse(s) + + logger.info("***** standard test *****") + stepcode_dir = normpath(os.path.expanduser('~/projects/src/stepcode')) + for d, _, files in os.walk(stepcode_dir): + for f in filter(lambda x: x.endswith('.stp'), files): + p = os.path.join(d, f) + try: + parse_check(p) + except LexError: + logger.exception('Lexer failure: {0}'.format(os.path.basename(p))) + + logger.info("***** finished *****") + + +if __name__ == '__main__': + #debug_lexer() + #debug_parser() + test() + diff --git a/src/exp2python/python/SCL/essa_par.py b/src/exp2python/python/stepcode/essa_par.py similarity index 81% rename from src/exp2python/python/SCL/essa_par.py rename to src/exp2python/python/stepcode/essa_par.py index 00f75957f..314a91d4e 100644 --- a/src/exp2python/python/SCL/essa_par.py +++ b/src/exp2python/python/stepcode/essa_par.py @@ -46,7 +46,7 @@ def process_nested_parent_str2(attr_str,idx=0): current_param = '' k += progress+1 elif ch==')': - #print "Down one level parenthesis: %i caracters parsed"%k + #print "Down one level parenthesis: %i characters parsed"%k params.append(current_param) #print "Current params:",params#k -= acc-2 return params,k @@ -54,21 +54,18 @@ def process_nested_parent_str2(attr_str,idx=0): current_param += ch #print "Ch:",ch #print "k:",k - + #raw_input("") #idx += 1 - + params.append(current_param) return params,k #print process_nested_parent_str2('1,2,3,4,5,6') #idx=0 #print process_nested_parent_str2("'A','B','C'") -print process_nested_parent_str2("'A'")[0] -print process_nested_parent_str2("30.0,0.0,5.0")[0] -print process_nested_parent_str2("(Thomas)")[0] -print process_nested_parent_str2("Thomas, Paviot, ouais")[0] -print process_nested_parent_str2("1,2,(3,4,5),6,7,8")[0] -print process_nested_parent_str2("(#9149,#9166),#9142,.T.")[0] - - - +print(process_nested_parent_str2("'A'")[0]) +print(process_nested_parent_str2("30.0,0.0,5.0")[0]) +print(process_nested_parent_str2("(Thomas)")[0]) +print(process_nested_parent_str2("Thomas, Paviot, ouais")[0]) +print(process_nested_parent_str2("1,2,(3,4,5),6,7,8")[0]) +print(process_nested_parent_str2("(#9149,#9166),#9142,.T.")[0]) diff --git a/src/exp2python/python/stepcode/p21sql.c b/src/exp2python/python/stepcode/p21sql.c new file mode 100644 index 000000000..d13fdf7eb --- /dev/null +++ b/src/exp2python/python/stepcode/p21sql.c @@ -0,0 +1,3512 @@ +/* Generated by re2c 1.0.3 on Mon Apr 6 21:17:12 2020 */ +#line 1 "p21sql.l" +/* +** 2015-08-12 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This SQLite extension implements P21 functions. The interface is +** modeled after MySQL JSON functions: +** +** https://dev.mysql.com/doc/refman/5.7/en/json.html +** +** For the time being, all P21 params are stored as pure text. +*/ +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_P21SQL) +#if !defined(SQLITEINT_H) +#include "sqlite3ext.h" +#endif +SQLITE_EXTENSION_INIT1 +#include +#include +#include +#include + +/* Mark a function parameter as unused, to suppress nuisance compiler +** warnings. */ +#ifndef UNUSED_PARAM +# define UNUSED_PARAM(X) (void)(X) +#endif + +#ifndef LARGEST_INT64 +# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) +#endif + +/* +** Versions of isspace(), isalnum() and isdigit() to which it is safe +** to pass signed char values. +*/ +#ifdef sqlite3Isdigit + /* Use the SQLite core versions if this routine is part of the + ** SQLite amalgamation */ +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) +#else + /* Use the standard library for separate compilation */ +#include /* amalgamator: keep */ +# define safe_isdigit(x) isdigit((unsigned char)(x)) +# define safe_isalnum(x) isalnum((unsigned char)(x)) +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) +#endif + +/* +** Growing our own isspace() routine this way is twice as fast as +** the library isspace() function, resulting in a 7% overall performance +** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). +*/ +static const char p21IsSpace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +#define safe_isspace(x) (p21IsSpace[(unsigned char)x]) + +#ifndef SQLITE_AMALGAMATION + /* Unsigned integer types. These are already defined in the sqliteInt.h, + ** but the definitions need to be repeated for separate compilation. */ + typedef sqlite3_uint64 u64; + typedef unsigned int u32; + typedef unsigned short int u16; + typedef unsigned char u8; +#endif + +/* some C implementations don't have these? (inttypes.h / stdint.h) */ +#ifndef UINT16_WIDTH +# define UINT16_WIDTH 16 +#endif +#ifndef UINT16_MAX +# define UINT16_MAX 65535 +#endif + +/* Objects */ +typedef struct P21String P21String; +typedef struct P21Node P21Node; +typedef struct P21Parse P21Parse; + +/* An instance of this object represents a P21 parameter string +** under construction. Really, this is a generic string accumulator +** that can be and is used to create strings other than JSON (here P21!). +*/ +struct P21String { + sqlite3_context *pCtx; /* Function context - put error messages here */ + char *zBuf; /* Append P21 content here */ + u64 nAlloc; /* Bytes of storage available in zBuf[] */ + u64 nUsed; /* Bytes of zBuf[] currently used */ + u8 bStatic; /* True if zBuf is static space */ + u8 bErr; /* True if an error has been encountered */ + char zSpace[100]; /* Initial static space */ +}; + +#define P21_EMPTY 0x1 /* optional attribute not provided : '$' */ +#define P21_DERIVED 0x2 /* derived attribute not provided : '*' */ +#define P21_ENUMERATION 0x3 /* (also) includes boolean and logical values */ +#define P21_INTEGER 0x4 +#define P21_REAL 0x5 +#define P21_STRING 0x6 +#define P21_BINARY 0x7 +#define P21_EID 0x8 /* entity_instance_name */ +#define P21_LIST 0x9 +#define P21_RECORD 0xA /* simple_record */ + +#define P21_SUBTYPE 80 /* Ascii for "P" */ + + +/* +** Names of the various P21 types: +*/ +static const char * const p21Type[] = { + "", + "empty", "derived", "enumeration", "integer", "real", + "string", "binary", "eid", "list", "record" +}; + +/* Bit values for the P21Node.jnFlag field +*/ +#define PNODE_RAW 0x01 /* Content is raw, not P21 encoded */ +#define PNODE_ESCAPE 0x02 /* Content is text with \ escapes */ +#define PNODE_REMOVE 0x04 /* Do not output */ +#define PNODE_REPLACE 0x08 /* Replace with P21Node.u.iReplace */ +#define PNODE_PATCH 0x10 /* Patch with P21Node.u.pPatch */ +#define PNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ +#define PNODE_LABEL 0x40 /* Is a label of an object */ + + +/* A single node of parsed P21 params +*/ +struct P21Node { + u8 eType; /* One of the P21_ type values */ + u8 jnFlags; /* P21Node flags */ + u16 n_kw; /* store the KEYWORD length */ + u32 n; /* Bytes of content, or number of sub-nodes */ + union { + const char *zJContent; /* Content for INT, REAL, and STRING */ + u32 iAppend; /* More terms for ARRAY and OBJECT */ + u32 iKey; /* Key for ARRAY objects in p21_tree() */ + u32 iReplace; /* Replacement content for PNODE_REPLACE */ + P21Node *pPatch; /* Node chain of patch for PNODE_PATCH */ + } u; +}; + +/* A completely parsed P21 string +*/ +struct P21Parse { + u32 nNode; /* Number of slots of aNode[] used */ + u32 nAlloc; /* Number of slots of aNode[] allocated */ + P21Node *aNode; /* Array of nodes containing the parse */ + const char *zP21; /* Original P21 string */ + u32 *aUp; /* Index of parent of each node */ + u8 oom; /* Set to true if out of memory */ + u8 nErr; /* Number of errors seen */ + u16 iDepth; /* Nesting depth */ + int nP21; /* Length of the zP21 string in bytes */ + u32 iHold; /* Replace cache line with the lowest iHold value */ +}; + +/* +** Maximum nesting depth of P21 for this implementation. +*/ +#define P21_MAX_DEPTH 20 + +/************************************************************************** +** Utility routines for dealing with P21String objects +**************************************************************************/ + +/* Set the P21String object to an empty string +*/ +static void p21Zero(P21String *p){ + p->zBuf = p->zSpace; + p->nAlloc = sizeof(p->zSpace); + p->nUsed = 0; + p->bStatic = 1; +} + +/* Initialize the P21String object +*/ +static void p21Init(P21String *p, sqlite3_context *pCtx){ + p->pCtx = pCtx; + p->bErr = 0; + p21Zero(p); +} + + +/* Free all allocated memory and reset the P21String object back to its +** initial state. +*/ +static void p21Reset(P21String *p){ + if( !p->bStatic ) sqlite3_free(p->zBuf); + p21Zero(p); +} + + +/* Report an out-of-memory (OOM) condition +*/ +static void p21Oom(P21String *p){ + p->bErr = 1; + sqlite3_result_error_nomem(p->pCtx); + p21Reset(p); +} + +/* Enlarge p->zBuf so that it can hold at least N more bytes. +** Return zero on success. Return non-zero on an OOM error +*/ +static int p21Grow(P21String *p, u32 N){ + u64 nTotal = NnAlloc ? p->nAlloc*2 : p->nAlloc+N+10; + char *zNew; + if( p->bStatic ){ + if( p->bErr ) return 1; + zNew = sqlite3_malloc64(nTotal); + if( zNew==0 ){ + p21Oom(p); + return SQLITE_NOMEM; + } + memcpy(zNew, p->zBuf, (size_t)p->nUsed); + p->zBuf = zNew; + p->bStatic = 0; + }else{ + zNew = sqlite3_realloc64(p->zBuf, nTotal); + if( zNew==0 ){ + p21Oom(p); + return SQLITE_NOMEM; + } + p->zBuf = zNew; + } + p->nAlloc = nTotal; + return SQLITE_OK; +} + +/* Append N bytes from zIn onto the end of the P21String string. +*/ +static void p21AppendRaw(P21String *p, const char *zIn, u32 N){ + if( (N+p->nUsed >= p->nAlloc) && p21Grow(p,N)!=0 ) return; + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; +} + +/* Append formatted text (not to exceed N bytes) to the P21String. +*/ +static void p21Printf(int N, P21String *p, const char *zFormat, ...){ + va_list ap; + if( (p->nUsed + N >= p->nAlloc) && p21Grow(p, N) ) return; + va_start(ap, zFormat); + sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); + va_end(ap); + p->nUsed += (int)strlen(p->zBuf+p->nUsed); +} + +/* Append a single character +*/ +static void p21AppendChar(P21String *p, char c){ + if( p->nUsed>=p->nAlloc && p21Grow(p,1)!=0 ) return; + p->zBuf[p->nUsed++] = c; +} + +/* Append a comma separator to the output buffer, if the previous +** character is not '[' or '{'. +*/ +static void p21AppendSeparator(P21String *p){ + char c; + if( p->nUsed==0 ) return; + c = p->zBuf[p->nUsed-1]; + if( c!='(' ) p21AppendChar(p, ','); +} + +/* Append the N-byte string in zIn to the end of the P21String string +** under construction. Enclose the string in '...' and escape +** any double-quotes or backslash characters contained within the +** string. +*/ +static void p21AppendString(P21String *p, const char *zIn, u32 N){ + u32 i; + if( (N+p->nUsed+2 >= p->nAlloc) && p21Grow(p,N+2)!=0 ) return; + p->zBuf[p->nUsed++] = '\''; + for(i=0; inUsed+N+3-i > p->nAlloc) && p21Grow(p,N+3-i)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + }else if( c<=0x1f ){ + static const char aSpecial[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assert( sizeof(aSpecial)==32 ); + assert( aSpecial['\b']=='b' ); + assert( aSpecial['\f']=='f' ); + assert( aSpecial['\n']=='n' ); + assert( aSpecial['\r']=='r' ); + assert( aSpecial['\t']=='t' ); + if( aSpecial[c] ){ + c = aSpecial[c]; + goto p21_simple_escape; + } + if( (p->nUsed+N+7+i > p->nAlloc) && p21Grow(p,N+7-i)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + p->zBuf[p->nUsed++] = 'u'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0' + (c>>4); + c = "0123456789abcdef"[c&0xf]; + } + p->zBuf[p->nUsed++] = c; + } + p->zBuf[p->nUsed++] = '\''; + assert( p->nUsednAlloc ); +} + +/* +** Append a function parameter value to the P21 string under +** construction. +*/ +static void p21AppendValue( + P21String *p, /* Append to this P21 string */ + sqlite3_value *pValue /* Value to append */ +){ + switch( sqlite3_value_type(pValue) ){ + case SQLITE_NULL: { + p21AppendRaw(p, "$", 1); + break; + } + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + const char *z = (const char*)sqlite3_value_text(pValue); + /* TODO: confirm format is valid */ + u32 n = (u32)sqlite3_value_bytes(pValue); + p21AppendRaw(p, z, n); + break; + } + case SQLITE_TEXT: { + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + if( sqlite3_value_subtype(pValue)==P21_SUBTYPE ){ + p21AppendRaw(p, z, n); + }else{ + p21AppendString(p, z, n); + } + break; + } + default: { + if( p->bErr==0 ){ + sqlite3_result_error(p->pCtx, "P21 cannot hold BLOB values", -1); + p->bErr = 2; + p21Reset(p); + } + break; + } + } +} + + +/* Make the P21 in p the result of the SQL function. +*/ +static void p21Result(P21String *p){ + if( p->bErr==0 ){ + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, + SQLITE_UTF8); + p21Zero(p); + } + assert( p->bStatic ); +} + +/************************************************************************** +** Utility routines for dealing with P21Node and P21Parse objects +**************************************************************************/ + +/* +** Return the number of consecutive P21Node slots need to represent +** the parsed P21 at pNode. The minimum answer is 1. For ARRAY and +** OBJECT types, the number might be larger. +** +** Appended elements are not counted. The value returned is the number +** by which the P21Node counter should increment in order to go to the +** next peer value. +*/ +static u32 p21NodeSize(P21Node *pNode){ + return pNode->eType < P21_LIST ? 1 : pNode->n + 1; +} + +/* +** Reclaim all memory allocated by a P21Parse object. But do not +** delete the P21Parse object itself. +*/ +static void p21ParseReset(P21Parse *pParse){ + sqlite3_free(pParse->aNode); + pParse->aNode = 0; + pParse->nNode = 0; + pParse->nAlloc = 0; + sqlite3_free(pParse->aUp); + pParse->aUp = 0; +} + +/* +** Free a P21Parse object that was obtained from sqlite3_malloc(). +*/ +static void p21ParseFree(P21Parse *pParse){ + p21ParseReset(pParse); + sqlite3_free(pParse); +} + +/* +** Convert the P21Node pNode into a pure P21 string and +** append to pOut. Subsubstructure is also included. Return +** the number of P21Node objects that are encoded. +*/ +static void p21RenderNode( + P21Node *pNode, /* The node to render */ + P21String *pOut, /* Write P21 here */ + sqlite3_value **aReplace /* Replacement values */ +){ + if( pNode->jnFlags & (PNODE_REPLACE|PNODE_PATCH) ){ + if( pNode->jnFlags & PNODE_REPLACE ){ + p21AppendValue(pOut, aReplace[pNode->u.iReplace]); + return; + } + pNode = pNode->u.pPatch; + } + switch( pNode->eType ){ + default: { + assert( pNode->eType==P21_EMPTY ); + p21AppendChar(pOut, '$'); + break; + } + case P21_ENUMERATION: { + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n); + break; + } + case P21_DERIVED: { + p21AppendChar(pOut, '*'); + break; + } + case P21_BINARY: { + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n); + break; + } + case P21_EID: { + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n); + break; + } + case P21_STRING: { + if( pNode->jnFlags & PNODE_RAW ){ + p21AppendString(pOut, pNode->u.zJContent, pNode->n); + break; + } + /* Fall through into the next case */ + } + case P21_REAL: + case P21_INTEGER: { + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n); + break; + } + case P21_LIST: { + u32 j = 1; + p21AppendChar(pOut, '('); + for(;;){ + while( j<=pNode->n ){ + if( (pNode[j].jnFlags & PNODE_REMOVE)==0 ){ + p21AppendSeparator(pOut); + p21RenderNode(&pNode[j], pOut, aReplace); + } + j += p21NodeSize(&pNode[j]); + } + if( (pNode->jnFlags & PNODE_APPEND)==0 ) break; + pNode = &pNode[pNode->u.iAppend]; + j = 1; + } + p21AppendChar(pOut, ')'); + break; + } + case P21_RECORD: { + u32 j = 1; + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n_kw); + p21AppendChar(pOut, '('); + for(;;){ + while( j<= pNode->n ){ + if( (pNode[j].jnFlags & PNODE_REMOVE)==0 ){ + p21AppendSeparator(pOut); + p21RenderNode(&pNode[j], pOut, aReplace); + } + j += p21NodeSize(&pNode[j]); + } + if( (pNode->jnFlags & PNODE_APPEND)==0 ) break; + pNode = &pNode[pNode->u.iAppend]; + j = 1; + } + p21AppendChar(pOut, ')'); + break; + } + } +} + +/* +** Return a P21Node and all its descendents as a P21 string. +*/ +static void p21ReturnP21( + P21Node *pNode, /* Node to return */ + sqlite3_context *pCtx, /* Return value for this function */ + sqlite3_value **aReplace /* Array of replacement values */ +){ + P21String s; + p21Init(&s, pCtx); + p21RenderNode(pNode, &s, aReplace); + p21Result(&s); + sqlite3_result_subtype(pCtx, P21_SUBTYPE); +} + +/* +** Translate a single byte of Hex into an integer. +** This routine only works if h really is a valid hexadecimal +** character: 0..9a..fA..F +*/ +static u8 p21HexToInt(int h){ + assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#else + h += 9*(1&(h>>6)); +#endif + return (u8)(h & 0xf); +} + +/* +** Convert a 4-byte hex string into an integer +*/ +static u32 p21HexToInt4(const char *z){ + u32 v; + assert( safe_isxdigit(z[0]) ); + assert( safe_isxdigit(z[1]) ); + assert( safe_isxdigit(z[2]) ); + assert( safe_isxdigit(z[3]) ); + v = (p21HexToInt(z[0])<<12) + + (p21HexToInt(z[1])<<8) + + (p21HexToInt(z[2])<<4) + + p21HexToInt(z[3]); + return v; +} +/* +** Make the P21Node the return value of the function. +*/ +static void p21Return( + P21Node *pNode, /* Node to return */ + sqlite3_context *pCtx, /* Return value for this function */ + sqlite3_value **aReplace /* Array of replacement values */ +){ + switch( pNode->eType ){ + default: { + assert( pNode->eType==P21_EMPTY ); + sqlite3_result_null(pCtx); + break; + } + case P21_DERIVED: { + assert(0); + } + case P21_ENUMERATION: { + assert(0); + } + case P21_BINARY: { + assert(0); + } + case P21_EID: { + sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, SQLITE_TRANSIENT); + break; + } + case P21_INTEGER: { + sqlite3_int64 i = 0; + const char *z = pNode->u.zJContent; + if( z[0]=='-' ){ z++; } + while( z[0]>='0' && z[0]<='9' ){ + unsigned v = *(z++) - '0'; + if( i>=LARGEST_INT64/10 ){ + if( i>LARGEST_INT64/10 ) goto int_as_real; + if( z[0]>='0' && z[0]<='9' ) goto int_as_real; + if( v==9 ) goto int_as_real; + if( v==8 ){ + if( pNode->u.zJContent[0]=='-' ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + goto int_done; + }else{ + goto int_as_real; + } + } + } + i = i*10 + v; + } + if( pNode->u.zJContent[0]=='-' ){ i = -i; } + sqlite3_result_int64(pCtx, i); + int_done: + break; + int_as_real: /* fall through to real */; + } + case P21_REAL: { + double r; +#ifdef SQLITE_AMALGAMATION + const char *z = pNode->u.zJContent; + sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); +#else + r = strtod(pNode->u.zJContent, 0); +#endif + sqlite3_result_double(pCtx, r); + break; + } + case P21_STRING: { +#if 0 /* Never happens because PNODE_RAW is only set by p21_set(), + ** p21_insert() and p21_replace() and those routines do not + ** call p21Return() */ + if( pNode->jnFlags & PNODE_RAW ){ + sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, + SQLITE_TRANSIENT); + }else +#endif + assert( (pNode->jnFlags & PNODE_RAW)==0 ); + if( (pNode->jnFlags & PNODE_ESCAPE)==0 ){ + /* P21 formatted without any backslash-escapes */ + sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, + SQLITE_TRANSIENT); + }else{ + /* Translate P21 formatted string into raw text */ + u32 i; + u32 n = pNode->n; + const char *z = pNode->u.zJContent; + char *zOut; + u32 j; + /* TODO: */ + assert(0); + zOut = sqlite3_malloc( n+1 ); + if( zOut==0 ){ + sqlite3_result_error_nomem(pCtx); + break; + } + for(i=1, j=0; i>6)); + zOut[j++] = 0x80 | (v&0x3f); + }else{ + u32 vlo; + if( (v&0xfc00)==0xd800 + && i>18); + zOut[j++] = 0x80 | ((v>>12)&0x3f); + zOut[j++] = 0x80 | ((v>>6)&0x3f); + zOut[j++] = 0x80 | (v&0x3f); + }else{ + zOut[j++] = 0xe0 | (v>>12); + zOut[j++] = 0x80 | ((v>>6)&0x3f); + zOut[j++] = 0x80 | (v&0x3f); + } + } + }else{ + if( c=='b' ){ + c = '\b'; + }else if( c=='f' ){ + c = '\f'; + }else if( c=='n' ){ + c = '\n'; + }else if( c=='r' ){ + c = '\r'; + }else if( c=='t' ){ + c = '\t'; + } + zOut[j++] = c; + } + } + } + zOut[j] = 0; + sqlite3_result_text(pCtx, zOut, j, sqlite3_free); + } + break; + } + case P21_LIST: + case P21_RECORD: { + p21ReturnP21(pNode, pCtx, aReplace); + break; + } + } +} + +/* Forward reference */ +static int p21ParseAddNode(P21Parse*,u32,u32,const char*); + +/* +** A macro to hint to the compiler that a function should not be +** inlined. +*/ +#if defined(__GNUC__) +# define P21_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) && _MSC_VER>=1310 +# define P21_NOINLINE __declspec(noinline) +#else +# define P21_NOINLINE +#endif + + +static P21_NOINLINE int p21ParseAddNodeExpand( + P21Parse *pParse, /* Append the node to this object */ + u32 eType, /* Node type */ + u32 n, /* Content size or sub-node count */ + const char *zContent /* Content */ +){ + u32 nNew; + P21Node *pNew; + assert( pParse->nNode>=pParse->nAlloc ); + if( pParse->oom ) return -1; + nNew = pParse->nAlloc*2 + 10; + pNew = sqlite3_realloc64(pParse->aNode, sizeof(P21Node)*nNew); + if( pNew==0 ){ + pParse->oom = 1; + return -1; + } + pParse->nAlloc = nNew; + pParse->aNode = pNew; + assert( pParse->nNodenAlloc ); + return p21ParseAddNode(pParse, eType, n, zContent); +} + +/* +** Create a new P21Node instance based on the arguments and append that +** instance to the P21Parse. Return the index in pParse->aNode[] of the +** new node, or -1 if a memory allocation fails. +*/ +static int p21ParseAddNode( + P21Parse *pParse, /* Append the node to this object */ + u32 eType, /* Node type */ + u32 n, /* Content size or sub-node count */ + const char *zContent /* Content */ +){ + P21Node *p; + if( pParse->nNode>=pParse->nAlloc ){ + return p21ParseAddNodeExpand(pParse, eType, n, zContent); + } + p = &pParse->aNode[pParse->nNode]; + p->eType = (u8)eType; + p->jnFlags = 0; + p->n = n; + p->u.zJContent = zContent; + return pParse->nNode++; +} + +/* +** Return true if z[] begins with 4 (or more) hexadecimal digits +*/ +static int p21Is4Hex(const char *z){ + int i; + for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; + return 1; +} + +/* +** Parse P21 value which begins at pParse->zP21[i]. Return the +** index of the first character past the end of the value parsed. +** +** Return negative for a syntax error. +*/ +static int p21ParseValue(P21Parse *pParse, u32 i) { + static int cxtStack[P21_MAX_DEPTH]; + const unsigned char *sp, *cur, *mrk, *tok, *end; + const unsigned char *yyt1; + int *piThis, x; + u32 n; + P21Node *pNode; + + sp = cur = tok = &pParse->zP21[i]; + piThis = cxtStack + pParse->iDepth; + +#line 832 "p21sql.l" + + +start: + + tok = cur; + +#line 822 "p21sql.c" +{ + unsigned char yych; + yych = *cur; + if (yych <= '\r') { + if (yych <= 0x0008) goto yy2; + if (yych <= '\n') goto yy3; + if (yych >= '\r') goto yy3; + } else { + if (yych <= ' ') { + if (yych >= ' ') goto yy3; + } else { + if (yych == '(') goto yy6; + } + } +yy2: +#line 850 "p21sql.l" + { + /* (simple_entity_instance) parameter_list */ + *piThis = p21ParseAddNode(pParse, P21_RECORD, 0, 0); + if (*piThis < 0) return -1; + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params1; + } +#line 848 "p21sql.c" +yy3: + yych = *++cur; + if (yych <= '\f') { + if (yych <= 0x0008) goto yy5; + if (yych <= '\n') goto yy3; + } else { + if (yych <= '\r') goto yy3; + if (yych == ' ') goto yy3; + } +yy5: +#line 838 "p21sql.l" + { + goto start; + } +#line 863 "p21sql.c" +yy6: + ++cur; +#line 841 "p21sql.l" + { + /* (complex_entity_instance) parameter_list */ + *piThis = p21ParseAddNode(pParse, P21_LIST, 0, 0); + if (*piThis < 0) return -1; + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto keywords; + } +#line 876 "p21sql.c" +} +#line 859 "p21sql.l" + + +keywords: + tok = cur; + + +#line 885 "p21sql.c" +{ + unsigned char yych; + yych = *(mrk = cur); + if (yych <= '(') { + if (yych <= '\r') { + if (yych <= 0x0008) goto yy10; + if (yych <= '\n') goto yy11; + if (yych >= '\r') goto yy11; + } else { + if (yych <= 0x001F) goto yy10; + if (yych <= ' ') goto yy11; + if (yych <= '!') goto yy14; + } + } else { + if (yych <= '^') { + if (yych <= ')') goto yy16; + if (yych <= '@') goto yy10; + if (yych <= 'Z') goto yy18; + } else { + if (yych == '`') goto yy10; + if (yych <= 'z') goto yy18; + } + } +yy10: +#line 885 "p21sql.l" + { + /* fix-up and revert to P21_RECORD */ + pNode = pParse->aNode + *(piThis - 1); + pNode->eType = P21_RECORD; + assert(pParse->iDepth == 1); + goto params1; + } +#line 918 "p21sql.c" +yy11: + yych = *++cur; + if (yych <= '\f') { + if (yych <= 0x0008) goto yy13; + if (yych <= '\n') goto yy11; + } else { + if (yych <= '\r') goto yy11; + if (yych == ' ') goto yy11; + } +yy13: +#line 865 "p21sql.l" + { + goto keywords; + } +#line 933 "p21sql.c" +yy14: + yych = *++cur; + if (yych <= '^') { + if (yych <= '@') goto yy15; + if (yych <= 'Z') goto yy18; + } else { + if (yych == '`') goto yy15; + if (yych <= 'z') goto yy18; + } +yy15: + cur = mrk; + goto yy10; +yy16: + ++cur; +#line 877 "p21sql.l" + { + piThis = cxtStack + --pParse->iDepth; + pNode = pParse->aNode + *piThis; + assert(pNode->eType == P21_LIST); + + pNode->n = pParse->nNode - (u32)*piThis - 1; + goto eol; + } +#line 957 "p21sql.c" +yy18: + yych = *++cur; + if (yych <= '(') { + if (yych <= '\r') { + if (yych <= 0x0008) goto yy15; + if (yych <= '\n') { + yyt1 = cur; + goto yy20; + } + if (yych <= '\f') goto yy15; + yyt1 = cur; + } else { + if (yych == ' ') { + yyt1 = cur; + goto yy20; + } + if (yych <= '\'') goto yy15; + yyt1 = cur; + goto yy22; + } + } else { + if (yych <= 'Z') { + if (yych <= '/') goto yy15; + if (yych <= '9') goto yy18; + if (yych <= '@') goto yy15; + goto yy18; + } else { + if (yych <= '_') { + if (yych <= '^') goto yy15; + goto yy18; + } else { + if (yych <= '`') goto yy15; + if (yych <= 'z') goto yy18; + goto yy15; + } + } + } +yy20: + yych = *++cur; + if (yych <= '\r') { + if (yych <= 0x0008) goto yy15; + if (yych <= '\n') goto yy20; + if (yych <= '\f') goto yy15; + goto yy20; + } else { + if (yych <= ' ') { + if (yych <= 0x001F) goto yy15; + goto yy20; + } else { + if (yych != '(') goto yy15; + } + } +yy22: + ++cur; + end = yyt1; +#line 868 "p21sql.l" + { + *piThis = p21ParseAddNode(pParse, P21_RECORD, 0, tok); + if (*piThis < 0) return -1; + pParse->aNode[*piThis].n_kw = (u16)(end - tok); + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params2; + } +#line 1023 "p21sql.c" +} +#line 892 "p21sql.l" + + +params1: + tok = cur; + + +#line 1032 "p21sql.c" +{ + unsigned char yych; + unsigned int yyaccept = 0; + yych = *(mrk = cur); + if (yych <= ')') { + if (yych <= '!') { + if (yych <= '\f') { + if (yych <= 0x0008) goto yy26; + if (yych <= '\n') goto yy27; + } else { + if (yych <= '\r') goto yy27; + if (yych <= 0x001F) goto yy26; + if (yych <= ' ') goto yy27; + goto yy30; + } + } else { + if (yych <= '$') { + if (yych <= '"') goto yy32; + if (yych <= '#') goto yy33; + goto yy34; + } else { + if (yych <= '&') goto yy26; + if (yych <= '\'') goto yy36; + if (yych <= '(') goto yy38; + goto yy40; + } + } + } else { + if (yych <= '9') { + if (yych <= ',') { + if (yych <= '*') goto yy42; + if (yych <= '+') goto yy44; + goto yy46; + } else { + if (yych <= '-') goto yy44; + if (yych <= '.') goto yy48; + if (yych >= '0') goto yy49; + } + } else { + if (yych <= '^') { + if (yych <= '@') goto yy26; + if (yych <= 'Z') goto yy52; + } else { + if (yych == '`') goto yy26; + if (yych <= 'z') goto yy52; + } + } + } +yy26: +#line 959 "p21sql.l" + { + if (pParse->iDepth) --pParse->iDepth; + piThis = cxtStack + pParse->iDepth; + pNode = pParse->aNode + *piThis; + assert(pNode->eType == P21_RECORD); + pNode->n = pParse->nNode - (u32)*piThis - 1; + goto eol; + } +#line 1091 "p21sql.c" +yy27: + yych = *++cur; + if (yych <= '\f') { + if (yych <= 0x0008) goto yy29; + if (yych <= '\n') goto yy27; + } else { + if (yych <= '\r') goto yy27; + if (yych == ' ') goto yy27; + } +yy29: +#line 898 "p21sql.l" + { + goto params1; + } +#line 1106 "p21sql.c" +yy30: + yych = *++cur; + if (yych <= '^') { + if (yych <= '@') goto yy31; + if (yych <= 'Z') goto yy52; + } else { + if (yych == '`') goto yy31; + if (yych <= 'z') goto yy52; + } +yy31: + cur = mrk; + if (yyaccept <= 1) { + if (yyaccept == 0) { + goto yy26; + } else { + goto yy60; + } + } else { + goto yy67; + } +yy32: + yych = *++cur; + if (yych <= '/') goto yy31; + if (yych <= '3') goto yy54; + goto yy31; +yy33: + yych = *++cur; + if (yych <= '/') goto yy31; + if (yych <= '9') goto yy56; + goto yy31; +yy34: + ++cur; +#line 945 "p21sql.l" + { + p21ParseAddNode(pParse, P21_EMPTY, cur - tok, tok); + goto params1; + } +#line 1144 "p21sql.c" +yy36: + yych = *++cur; + if (yych <= 'Z') { + if (yych <= 0x001F) goto yy31; + if (yych == '\'') goto yy59; + goto yy36; + } else { + if (yych <= '\\') { + if (yych <= '[') goto yy31; + goto yy61; + } else { + if (yych <= ']') goto yy31; + if (yych <= '~') goto yy36; + goto yy31; + } + } +yy38: + ++cur; +#line 910 "p21sql.l" + { + *piThis = p21ParseAddNode(pParse, P21_LIST, 0, 0); + if (*piThis < 0) return -1; + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params1; + } +#line 1172 "p21sql.c" +yy40: + ++cur; +#line 953 "p21sql.l" + { + piThis = cxtStack + --pParse->iDepth; + pNode = pParse->aNode + *piThis; + pNode->n = pParse->nNode - (u32)*piThis - 1; + goto params1; + } +#line 1182 "p21sql.c" +yy42: + ++cur; +#line 949 "p21sql.l" + { + p21ParseAddNode(pParse, P21_DERIVED, cur - tok, tok); + goto params1; + } +#line 1190 "p21sql.c" +yy44: + yych = *++cur; + if (yych <= ',') { + if (yych == '+') goto yy44; + goto yy31; + } else { + if (yych <= '-') goto yy44; + if (yych <= '/') goto yy31; + if (yych <= '9') goto yy49; + goto yy31; + } +yy46: + ++cur; +#line 918 "p21sql.l" + { + goto params1; + } +#line 1208 "p21sql.c" +yy48: + yych = *++cur; + if (yych <= '@') goto yy31; + if (yych <= 'Z') goto yy63; + if (yych == '_') goto yy63; + goto yy31; +yy49: + yych = *++cur; + if (yych == '.') goto yy65; + if (yych <= '/') goto yy51; + if (yych <= '9') goto yy49; +yy51: +#line 925 "p21sql.l" + { + p21ParseAddNode(pParse, P21_INTEGER, cur - tok, tok); + goto params1; + } +#line 1226 "p21sql.c" +yy52: + yych = *++cur; + if (yych <= '(') { + if (yych <= '\r') { + if (yych <= 0x0008) goto yy31; + if (yych <= '\n') { + yyt1 = cur; + goto yy68; + } + if (yych <= '\f') goto yy31; + yyt1 = cur; + goto yy68; + } else { + if (yych == ' ') { + yyt1 = cur; + goto yy68; + } + if (yych <= '\'') goto yy31; + yyt1 = cur; + goto yy70; + } + } else { + if (yych <= 'Z') { + if (yych <= '/') goto yy31; + if (yych <= '9') goto yy52; + if (yych <= '@') goto yy31; + goto yy52; + } else { + if (yych <= '_') { + if (yych <= '^') goto yy31; + goto yy52; + } else { + if (yych <= '`') goto yy31; + if (yych <= 'z') goto yy52; + goto yy31; + } + } + } +yy54: + yych = *++cur; + if (yych <= '/') { + if (yych == '"') goto yy72; + goto yy31; + } else { + if (yych <= '9') goto yy54; + if (yych <= '@') goto yy31; + if (yych <= 'F') goto yy54; + goto yy31; + } +yy56: + yych = *++cur; + if (yych <= '/') goto yy58; + if (yych <= '9') goto yy56; +yy58: +#line 941 "p21sql.l" + { + p21ParseAddNode(pParse, P21_EID, cur - tok, tok); + goto params1; + } +#line 1286 "p21sql.c" +yy59: + yyaccept = 1; + yych = *(mrk = ++cur); + if (yych == '\'') goto yy36; +yy60: +#line 929 "p21sql.l" + { + p21ParseAddNode(pParse, P21_STRING, cur - tok, tok); + goto params1; + } +#line 1297 "p21sql.c" +yy61: + yych = *++cur; + if (yych <= 'S') { + if (yych <= '&') { + if (yych <= 0x001F) goto yy31; + goto yy36; + } else { + if (yych <= '\'') goto yy59; + if (yych <= 'R') goto yy36; + goto yy74; + } + } else { + if (yych <= '\\') { + if (yych <= 'Z') goto yy36; + if (yych <= '[') goto yy31; + goto yy61; + } else { + if (yych <= ']') goto yy31; + if (yych <= '~') goto yy36; + goto yy31; + } + } +yy63: + yych = *++cur; + if (yych <= '9') { + if (yych == '.') goto yy75; + if (yych <= '/') goto yy31; + goto yy63; + } else { + if (yych <= 'Z') { + if (yych <= '@') goto yy31; + goto yy63; + } else { + if (yych == '_') goto yy63; + goto yy31; + } + } +yy65: + yyaccept = 2; + yych = *(mrk = ++cur); + if (yych <= '/') goto yy67; + if (yych <= '9') goto yy65; + if (yych == 'E') goto yy77; +yy67: +#line 921 "p21sql.l" + { + p21ParseAddNode(pParse, P21_REAL, cur - tok, tok); + goto params1; + } +#line 1347 "p21sql.c" +yy68: + yych = *++cur; + if (yych <= '\r') { + if (yych <= 0x0008) goto yy31; + if (yych <= '\n') goto yy68; + if (yych <= '\f') goto yy31; + goto yy68; + } else { + if (yych <= ' ') { + if (yych <= 0x001F) goto yy31; + goto yy68; + } else { + if (yych != '(') goto yy31; + } + } +yy70: + ++cur; + end = yyt1; +#line 901 "p21sql.l" + { + *piThis = p21ParseAddNode(pParse, P21_RECORD, 0, tok); + if (*piThis < 0) return -1; + pParse->aNode[*piThis].n_kw = (u16)(end - tok); + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params1; + } +#line 1376 "p21sql.c" +yy72: + ++cur; +#line 933 "p21sql.l" + { + p21ParseAddNode(pParse, P21_BINARY, cur - tok, tok); + goto params1; + } +#line 1384 "p21sql.c" +yy74: + yych = *++cur; + if (yych <= 'Z') { + if (yych <= 0x001F) goto yy31; + if (yych == '\'') goto yy59; + goto yy36; + } else { + if (yych <= '\\') { + if (yych <= '[') goto yy31; + goto yy79; + } else { + if (yych <= ']') goto yy31; + if (yych <= '~') goto yy36; + goto yy31; + } + } +yy75: + ++cur; +#line 937 "p21sql.l" + { + p21ParseAddNode(pParse, P21_ENUMERATION, cur - tok, tok); + goto params1; + } +#line 1408 "p21sql.c" +yy77: + yych = *++cur; + if (yych <= ',') { + if (yych == '+') goto yy77; + goto yy31; + } else { + if (yych <= '-') goto yy77; + if (yych <= '/') goto yy31; + if (yych <= '9') goto yy80; + goto yy31; + } +yy79: + yych = *++cur; + if (yych <= 'S') { + if (yych <= '&') { + if (yych <= 0x001F) goto yy31; + goto yy36; + } else { + if (yych <= '\'') goto yy82; + if (yych <= 'R') goto yy36; + goto yy74; + } + } else { + if (yych <= '\\') { + if (yych <= 'Z') goto yy36; + if (yych <= '[') goto yy31; + goto yy61; + } else { + if (yych <= ']') goto yy31; + if (yych <= '~') goto yy36; + goto yy31; + } + } +yy80: + yych = *++cur; + if (yych <= '/') goto yy67; + if (yych <= '9') goto yy80; + goto yy67; +yy82: + yyaccept = 1; + yych = *(mrk = ++cur); + if (yych <= 'Z') { + if (yych <= 0x001F) goto yy60; + if (yych == '\'') goto yy82; + goto yy36; + } else { + if (yych <= '\\') { + if (yych <= '[') goto yy60; + goto yy61; + } else { + if (yych <= ']') goto yy60; + if (yych <= '~') goto yy36; + goto yy60; + } + } +} +#line 967 "p21sql.l" + + +params2: + tok = cur; + + +#line 1472 "p21sql.c" +{ + unsigned char yych; + unsigned int yyaccept = 0; + yych = *cur; + if (yych <= ')') { + if (yych <= '!') { + if (yych <= '\f') { + if (yych <= 0x0008) goto yy86; + if (yych <= '\n') goto yy87; + } else { + if (yych <= '\r') goto yy87; + if (yych <= 0x001F) goto yy86; + if (yych <= ' ') goto yy87; + goto yy90; + } + } else { + if (yych <= '$') { + if (yych <= '"') goto yy91; + if (yych <= '#') goto yy92; + goto yy93; + } else { + if (yych <= '&') goto yy86; + if (yych <= '\'') goto yy95; + if (yych <= '(') goto yy97; + goto yy99; + } + } + } else { + if (yych <= '9') { + if (yych <= ',') { + if (yych <= '*') goto yy101; + if (yych <= '+') goto yy103; + goto yy105; + } else { + if (yych <= '-') goto yy103; + if (yych <= '.') goto yy107; + if (yych >= '0') goto yy108; + } + } else { + if (yych <= '^') { + if (yych <= '@') goto yy86; + if (yych <= 'Z') goto yy111; + } else { + if (yych == '`') goto yy86; + if (yych <= 'z') goto yy111; + } + } + } +yy86: + cur = mrk; + if (yyaccept == 0) { + goto yy119; + } else { + goto yy126; + } +yy87: + yych = *++cur; + if (yych <= '\f') { + if (yych <= 0x0008) goto yy89; + if (yych <= '\n') goto yy87; + } else { + if (yych <= '\r') goto yy87; + if (yych == ' ') goto yy87; + } +yy89: +#line 973 "p21sql.l" + { + goto params2; + } +#line 1542 "p21sql.c" +yy90: + yych = *++cur; + if (yych <= '^') { + if (yych <= '@') goto yy86; + if (yych <= 'Z') goto yy111; + goto yy86; + } else { + if (yych == '`') goto yy86; + if (yych <= 'z') goto yy111; + goto yy86; + } +yy91: + yych = *++cur; + if (yych <= '/') goto yy86; + if (yych <= '3') goto yy113; + goto yy86; +yy92: + yych = *++cur; + if (yych <= '/') goto yy86; + if (yych <= '9') goto yy115; + goto yy86; +yy93: + ++cur; +#line 1020 "p21sql.l" + { + p21ParseAddNode(pParse, P21_EMPTY, cur - tok, tok); + goto params2; + } +#line 1571 "p21sql.c" +yy95: + yych = *++cur; + if (yych <= 'Z') { + if (yych <= 0x001F) goto yy86; + if (yych == '\'') goto yy118; + goto yy95; + } else { + if (yych <= '\\') { + if (yych <= '[') goto yy86; + goto yy120; + } else { + if (yych <= ']') goto yy86; + if (yych <= '~') goto yy95; + goto yy86; + } + } +yy97: + ++cur; +#line 985 "p21sql.l" + { + *piThis = p21ParseAddNode(pParse, P21_LIST, 0, 0); + if (*piThis < 0) return -1; + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params2; + } +#line 1599 "p21sql.c" +yy99: + ++cur; +#line 1028 "p21sql.l" + { + piThis = cxtStack + --pParse->iDepth; + pNode = pParse->aNode + *piThis; + pNode->n = pParse->nNode - (u32)*piThis - 1; + if (pParse->iDepth > 1) { + goto params2; + } else { + goto keywords; + } + } +#line 1613 "p21sql.c" +yy101: + ++cur; +#line 1024 "p21sql.l" + { + p21ParseAddNode(pParse, P21_DERIVED, cur - tok, tok); + goto params2; + } +#line 1621 "p21sql.c" +yy103: + yych = *++cur; + if (yych <= ',') { + if (yych == '+') goto yy103; + goto yy86; + } else { + if (yych <= '-') goto yy103; + if (yych <= '/') goto yy86; + if (yych <= '9') goto yy108; + goto yy86; + } +yy105: + ++cur; +#line 993 "p21sql.l" + { + goto params2; + } +#line 1639 "p21sql.c" +yy107: + yych = *++cur; + if (yych <= '@') goto yy86; + if (yych <= 'Z') goto yy122; + if (yych == '_') goto yy122; + goto yy86; +yy108: + yych = *++cur; + if (yych == '.') goto yy124; + if (yych <= '/') goto yy110; + if (yych <= '9') goto yy108; +yy110: +#line 1000 "p21sql.l" + { + p21ParseAddNode(pParse, P21_INTEGER, cur - tok, tok); + goto params2; + } +#line 1657 "p21sql.c" +yy111: + yych = *++cur; + if (yych <= '(') { + if (yych <= '\r') { + if (yych <= 0x0008) goto yy86; + if (yych <= '\n') { + yyt1 = cur; + goto yy127; + } + if (yych <= '\f') goto yy86; + yyt1 = cur; + goto yy127; + } else { + if (yych == ' ') { + yyt1 = cur; + goto yy127; + } + if (yych <= '\'') goto yy86; + yyt1 = cur; + goto yy129; + } + } else { + if (yych <= 'Z') { + if (yych <= '/') goto yy86; + if (yych <= '9') goto yy111; + if (yych <= '@') goto yy86; + goto yy111; + } else { + if (yych <= '_') { + if (yych <= '^') goto yy86; + goto yy111; + } else { + if (yych <= '`') goto yy86; + if (yych <= 'z') goto yy111; + goto yy86; + } + } + } +yy113: + yych = *++cur; + if (yych <= '/') { + if (yych == '"') goto yy131; + goto yy86; + } else { + if (yych <= '9') goto yy113; + if (yych <= '@') goto yy86; + if (yych <= 'F') goto yy113; + goto yy86; + } +yy115: + yych = *++cur; + if (yych <= '/') goto yy117; + if (yych <= '9') goto yy115; +yy117: +#line 1016 "p21sql.l" + { + p21ParseAddNode(pParse, P21_EID, cur - tok, tok); + goto params2; + } +#line 1717 "p21sql.c" +yy118: + yyaccept = 0; + yych = *(mrk = ++cur); + if (yych == '\'') goto yy95; +yy119: +#line 1004 "p21sql.l" + { + p21ParseAddNode(pParse, P21_STRING, cur - tok, tok); + goto params2; + } +#line 1728 "p21sql.c" +yy120: + yych = *++cur; + if (yych <= 'S') { + if (yych <= '&') { + if (yych <= 0x001F) goto yy86; + goto yy95; + } else { + if (yych <= '\'') goto yy118; + if (yych <= 'R') goto yy95; + goto yy133; + } + } else { + if (yych <= '\\') { + if (yych <= 'Z') goto yy95; + if (yych <= '[') goto yy86; + goto yy120; + } else { + if (yych <= ']') goto yy86; + if (yych <= '~') goto yy95; + goto yy86; + } + } +yy122: + yych = *++cur; + if (yych <= '9') { + if (yych == '.') goto yy134; + if (yych <= '/') goto yy86; + goto yy122; + } else { + if (yych <= 'Z') { + if (yych <= '@') goto yy86; + goto yy122; + } else { + if (yych == '_') goto yy122; + goto yy86; + } + } +yy124: + yyaccept = 1; + yych = *(mrk = ++cur); + if (yych <= '/') goto yy126; + if (yych <= '9') goto yy124; + if (yych == 'E') goto yy136; +yy126: +#line 996 "p21sql.l" + { + p21ParseAddNode(pParse, P21_REAL, cur - tok, tok); + goto params2; + } +#line 1778 "p21sql.c" +yy127: + yych = *++cur; + if (yych <= '\r') { + if (yych <= 0x0008) goto yy86; + if (yych <= '\n') goto yy127; + if (yych <= '\f') goto yy86; + goto yy127; + } else { + if (yych <= ' ') { + if (yych <= 0x001F) goto yy86; + goto yy127; + } else { + if (yych != '(') goto yy86; + } + } +yy129: + ++cur; + end = yyt1; +#line 976 "p21sql.l" + { + *piThis = p21ParseAddNode(pParse, P21_RECORD, 0, tok); + if (*piThis < 0) return -1; + pParse->aNode[*piThis].n_kw = (u16)(end - tok); + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params2; + } +#line 1807 "p21sql.c" +yy131: + ++cur; +#line 1008 "p21sql.l" + { + p21ParseAddNode(pParse, P21_BINARY, cur - tok, tok); + goto params2; + } +#line 1815 "p21sql.c" +yy133: + yych = *++cur; + if (yych <= 'Z') { + if (yych <= 0x001F) goto yy86; + if (yych == '\'') goto yy118; + goto yy95; + } else { + if (yych <= '\\') { + if (yych <= '[') goto yy86; + goto yy138; + } else { + if (yych <= ']') goto yy86; + if (yych <= '~') goto yy95; + goto yy86; + } + } +yy134: + ++cur; +#line 1012 "p21sql.l" + { + p21ParseAddNode(pParse, P21_ENUMERATION, cur - tok, tok); + goto params2; + } +#line 1839 "p21sql.c" +yy136: + yych = *++cur; + if (yych <= ',') { + if (yych == '+') goto yy136; + goto yy86; + } else { + if (yych <= '-') goto yy136; + if (yych <= '/') goto yy86; + if (yych <= '9') goto yy139; + goto yy86; + } +yy138: + yych = *++cur; + if (yych <= 'S') { + if (yych <= '&') { + if (yych <= 0x001F) goto yy86; + goto yy95; + } else { + if (yych <= '\'') goto yy141; + if (yych <= 'R') goto yy95; + goto yy133; + } + } else { + if (yych <= '\\') { + if (yych <= 'Z') goto yy95; + if (yych <= '[') goto yy86; + goto yy120; + } else { + if (yych <= ']') goto yy86; + if (yych <= '~') goto yy95; + goto yy86; + } + } +yy139: + yych = *++cur; + if (yych <= '/') goto yy126; + if (yych <= '9') goto yy139; + goto yy126; +yy141: + yyaccept = 0; + yych = *(mrk = ++cur); + if (yych <= 'Z') { + if (yych <= 0x001F) goto yy119; + if (yych == '\'') goto yy141; + goto yy95; + } else { + if (yych <= '\\') { + if (yych <= '[') goto yy119; + goto yy120; + } else { + if (yych <= ']') goto yy119; + if (yych <= '~') goto yy95; + goto yy119; + } + } +} +#line 1039 "p21sql.l" + + +eol: + tok = cur; + + +#line 1903 "p21sql.c" +{ + unsigned char yych; + yych = *cur; + if (yych >= 0x0001) goto yy147; + ++cur; +#line 1045 "p21sql.l" + { + return cur - sp; + } +#line 1913 "p21sql.c" +yy147: + ++cur; +#line 1048 "p21sql.l" + { + return -1; + } +#line 1920 "p21sql.c" +} +#line 1051 "p21sql.l" + + +} + + +/* +** Parse a complete P21 string. Return 0 on success or non-zero if there +** are any errors. If an error occurs, free all memory associated with +** pParse. +** +** pParse is uninitialized when this routine is called. +*/ +static int p21Parse( + P21Parse *pParse, /* Initialize and fill this P21Parse object */ + sqlite3_context *pCtx, /* Report errors here */ + const char *zP21 /* Input P21 text to be parsed */ +){ + int i; + memset(pParse, 0, sizeof(*pParse)); + if( zP21==0 ) return 1; + pParse->zP21 = zP21; + i = p21ParseValue(pParse, 0); + if( pParse->oom ) i = -1; + if( i>0 ){ + assert( pParse->iDepth==0 ); + } + if( i<=0 ){ + if( pCtx!=0 ){ + if( pParse->oom ){ + sqlite3_result_error_nomem(pCtx); + }else{ + sqlite3_result_error(pCtx, "malformed P21", -1); + } + } + p21ParseReset(pParse); + return 1; + } + return 0; +} + +/* Mark node i of pParse as being a child of iParent. Call recursively +** to fill in all the descendants of node i. +*/ +static void p21ParseFillInParentage(P21Parse *pParse, u32 i, u32 iParent){ + P21Node *pNode = &pParse->aNode[i]; + u32 j; + pParse->aUp[i] = iParent; + switch( pNode->eType ){ + case P21_RECORD: + case P21_LIST: { + for(j=1; j<=pNode->n; j += p21NodeSize(pNode+j)){ + p21ParseFillInParentage(pParse, i+j, i); + } + break; + } + default: { + break; + } + } +} + +/* +** Compute the parentage of all nodes in a completed parse. +*/ +static int p21ParseFindParents(P21Parse *pParse){ + u32 *aUp; + assert( pParse->aUp==0 ); + aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode ); + if( aUp==0 ){ + pParse->oom = 1; + return SQLITE_NOMEM; + } + p21ParseFillInParentage(pParse, 0, 0); + return SQLITE_OK; +} + +/* +** Magic number used for the P21 parse cache in sqlite3_get_auxdata() +*/ +#define P21_CACHE_ID (-429938) /* First cache entry */ +#define P21_CACHE_SZ 4 /* Max number of cache entries */ + +/* +** Obtain a complete parse of the P21 found in the first argument +** of the argv array. Use the sqlite3_get_auxdata() cache for this +** parse if it is available. If the cache is not available or if it +** is no longer valid, parse the P21 again and return the new parse, +** and also register the new parse so that it will be available for +** future sqlite3_get_auxdata() calls. +*/ +static P21Parse *p21ParseCached( + sqlite3_context *pCtx, + sqlite3_value **argv, + sqlite3_context *pErrCtx +){ + const char *zP21 = (const char*)sqlite3_value_text(argv[0]); + int nP21 = sqlite3_value_bytes(argv[0]); + P21Parse *p; + P21Parse *pMatch = 0; + int iKey; + int iMinKey = 0; + u32 iMinHold = 0xffffffff; + u32 iMaxHold = 0; + if( zP21==0 ) return 0; + for(iKey=0; iKeynP21==nP21 + && memcmp(p->zP21,zP21,nP21)==0 + ){ + p->nErr = 0; + pMatch = p; + }else if( p->iHoldiHold; + iMinKey = iKey; + } + if( p->iHold>iMaxHold ){ + iMaxHold = p->iHold; + } + } + if( pMatch ){ + pMatch->nErr = 0; + pMatch->iHold = iMaxHold+1; + return pMatch; + } + p = sqlite3_malloc64( sizeof(*p) + nP21 + 1 ); + if( p==0 ){ + sqlite3_result_error_nomem(pCtx); + return 0; + } + memset(p, 0, sizeof(*p)); + p->zP21 = (char*)&p[1]; + memcpy((char*)p->zP21, zP21, nP21+1); + if( p21Parse(p, pErrCtx, p->zP21) ){ + sqlite3_free(p); + return 0; + } + p->nP21 = nP21; + p->iHold = iMaxHold+1; + sqlite3_set_auxdata(pCtx, P21_CACHE_ID+iMinKey, p, + (void(*)(void*))p21ParseFree); + return (P21Parse*)sqlite3_get_auxdata(pCtx, P21_CACHE_ID+iMinKey); +} + +/* +** Compare the OBJECT label at pNode against zKey,nKey. Return true on +** a match. +*/ +static int p21LabelCompare(P21Node *pNode, const char *zKey, u32 nKey){ + if( pNode->jnFlags & PNODE_RAW ){ + if( pNode->n!=nKey ) return 0; + return strncmp(pNode->u.zJContent, zKey, nKey)==0; + }else{ + if( pNode->n!=nKey+2 ) return 0; + return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; + } +} + +/* forward declaration */ +static P21Node *p21LookupAppend(P21Parse*,const char*,int*,const char**); + +/* +** Search along zPath to find the node specified. Return a pointer +** to that node, or NULL if zPath is malformed or if there is no such +** node. +** +** If pApnd!=0, then try to append new nodes to complete zPath if it is +** possible to do so and if no existing node corresponds to zPath. If +** new nodes are appended *pApnd is set to 1. +*/ +static P21Node *p21LookupStep( + P21Parse *pParse, /* The P21 to search */ + u32 iRoot, /* Begin the search at this node */ + const char *zPath, /* The path to search */ + int *pApnd, /* Append nodes to complete path if not NULL */ + const char **pzErr /* Make *pzErr point to any syntax error in zPath */ +){ + u32 i, j, nKey; + const char *zKey; + P21Node *pRoot = &pParse->aNode[iRoot]; + if( zPath[0]==0 ) return pRoot; + if( pRoot->jnFlags & PNODE_REPLACE ) return 0; + if( zPath[0]=='.' ){ + if( pRoot->eType!=P21_RECORD ) return 0; + zPath++; + if( zPath[0]=='"' ){ + zKey = zPath + 1; + for(i=1; zPath[i] && zPath[i]!='"'; i++){} + nKey = i-1; + if( zPath[i] ){ + i++; + }else{ + *pzErr = zPath; + return 0; + } + }else{ + zKey = zPath; + for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} + nKey = i; + } + if( nKey==0 ){ + *pzErr = zPath; + return 0; + } + j = 1; + for(;;){ + while( j<=pRoot->n ){ + if( p21LabelCompare(pRoot+j, zKey, nKey) ){ + return p21LookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); + } + j++; + j += p21NodeSize(&pRoot[j]); + } + if( (pRoot->jnFlags & PNODE_APPEND)==0 ) break; + iRoot += pRoot->u.iAppend; + pRoot = &pParse->aNode[iRoot]; + j = 1; + } + if( pApnd ){ + u32 iStart, iLabel; + P21Node *pNode; + iStart = p21ParseAddNode(pParse, P21_RECORD, 2, 0); + iLabel = p21ParseAddNode(pParse, P21_STRING, nKey, zKey); + zPath += i; + pNode = p21LookupAppend(pParse, zPath, pApnd, pzErr); + if( pParse->oom ) return 0; + if( pNode ){ + pRoot = &pParse->aNode[iRoot]; + pRoot->u.iAppend = iStart - iRoot; + pRoot->jnFlags |= PNODE_APPEND; + pParse->aNode[iLabel].jnFlags |= PNODE_RAW; + } + return pNode; + } + }else if( zPath[0]=='[' ){ + i = 0; + j = 1; + while( safe_isdigit(zPath[j]) ){ + i = i*10 + zPath[j] - '0'; + j++; + } + if( j<2 || zPath[j]!=']' ){ + if( zPath[1]=='#' ){ + P21Node *pBase = pRoot; + int iBase = iRoot; + if( pRoot->eType!=P21_LIST && pRoot->eType!=P21_RECORD) return 0; + for(;;){ + while( j<=pBase->n ){ + if( (pBase[j].jnFlags & PNODE_REMOVE)==0 ) i++; + j += p21NodeSize(&pBase[j]); + } + if( (pBase->jnFlags & PNODE_APPEND)==0 ) break; + iBase += pBase->u.iAppend; + pBase = &pParse->aNode[iBase]; + j = 1; + } + j = 2; + if( zPath[2]=='-' && safe_isdigit(zPath[3]) ){ + unsigned int x = 0; + j = 3; + do{ + x = x*10 + zPath[j] - '0'; + j++; + }while( safe_isdigit(zPath[j]) ); + if( x>i ) return 0; + i -= x; + } + if( zPath[j]!=']' ){ + *pzErr = zPath; + return 0; + } + }else{ + *pzErr = zPath; + return 0; + } + } + if( pRoot->eType!=P21_LIST && pRoot->eType!=P21_RECORD ) return 0; + zPath += j + 1; + j = 1; + for(;;){ + while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & PNODE_REMOVE)!=0) ){ + if( (pRoot[j].jnFlags & PNODE_REMOVE)==0 ) i--; + j += p21NodeSize(&pRoot[j]); + } + if( (pRoot->jnFlags & PNODE_APPEND)==0 ) break; + iRoot += pRoot->u.iAppend; + pRoot = &pParse->aNode[iRoot]; + j = 1; + } + if( j<=pRoot->n ){ + return p21LookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); + } + if( i==0 && pApnd ){ + u32 iStart; + P21Node *pNode; + iStart = p21ParseAddNode(pParse, P21_LIST, 1, 0); + pNode = p21LookupAppend(pParse, zPath, pApnd, pzErr); + if( pParse->oom ) return 0; + if( pNode ){ + pRoot = &pParse->aNode[iRoot]; + pRoot->u.iAppend = iStart - iRoot; + pRoot->jnFlags |= PNODE_APPEND; + } + return pNode; + } + }else{ + *pzErr = zPath; + } + return 0; +} + +/* +** Append content to pParse that will complete zPath. Return a pointer +** to the inserted node, or return NULL if the append fails. +*/ +static P21Node *p21LookupAppend( + P21Parse *pParse, /* Append content to the P21 parse */ + const char *zPath, /* Description of content to append */ + int *pApnd, /* Set this flag to 1 */ + const char **pzErr /* Make this point to any syntax error */ +){ + *pApnd = 1; + if( zPath[0]==0 ){ + p21ParseAddNode(pParse, P21_EMPTY, 0, 0); + return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; + } + if( zPath[0]=='.' ){ + p21ParseAddNode(pParse, P21_RECORD, 0, 0); + }else if( strncmp(zPath,"[0]",3)==0 ){ + p21ParseAddNode(pParse, P21_LIST, 0, 0); + }else{ + return 0; + } + if( pParse->oom ) return 0; + return p21LookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); +} + +/* +** Return the text of a syntax error message on a P21 path. Space is +** obtained from sqlite3_malloc(). +*/ +static char *p21PathSyntaxError(const char *zErr){ + return sqlite3_mprintf("P21 path error near '%q'", zErr); +} + +/* +** Do a node lookup using zPath. Return a pointer to the node on success. +** Return NULL if not found or if there is an error. +** +** On an error, write an error message into pCtx and increment the +** pParse->nErr counter. +** +** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if +** nodes are appended. +*/ +static P21Node *p21Lookup( + P21Parse *pParse, /* The P21 to search */ + const char *zPath, /* The path to search */ + int *pApnd, /* Append nodes to complete path if not NULL */ + sqlite3_context *pCtx /* Report errors here, if not NULL */ +){ + const char *zErr = 0; + P21Node *pNode = 0; + char *zMsg; + + if( zPath==0 ) return 0; + if( zPath[0]!='$' ){ + zErr = zPath; + goto lookup_err; + } + zPath++; + pNode = p21LookupStep(pParse, 0, zPath, pApnd, &zErr); + if( zErr==0 ) return pNode; + +lookup_err: + pParse->nErr++; + assert( zErr!=0 && pCtx!=0 ); + zMsg = p21PathSyntaxError(zErr); + if( zMsg ){ + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); + }else{ + sqlite3_result_error_nomem(pCtx); + } + return 0; +} + + +/* +** Report the wrong number of arguments for p21_insert(), p21_replace() +** or p21_set(). +*/ +static void p21WrongNumArgs( + sqlite3_context *pCtx, + const char *zFuncName +){ + char *zMsg = sqlite3_mprintf("p21_%s() needs an odd number of arguments", + zFuncName); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); +} + +/* +** Mark all NULL entries in the Object passed in as PNODE_REMOVE. +*/ +static void p21RemoveAllNulls(P21Node *pNode){ + int i, n; + assert( pNode->eType==P21_RECORD ); + n = pNode->n; + for(i=2; i<=n; i += p21NodeSize(&pNode[i])+1){ + switch( pNode[i].eType ){ + case P21_EMPTY: + pNode[i].jnFlags |= PNODE_REMOVE; + break; + case P21_RECORD: + p21RemoveAllNulls(&pNode[i]); + break; + } + } +} + + +/**************************************************************************** +** SQL functions used for testing and debugging +****************************************************************************/ + +#ifdef SQLITE_DEBUG +/* +** The p21_parse(P21) function returns a string which describes +** a parse of the P21 provided. Or it returns NULL if P21 is not +** well-formed. +*/ +static void p21ParseFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21String s; /* Output string - not real P21 */ + P21Parse x; /* The parse */ + u32 i; + + assert( argc==1 ); + if( p21Parse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + p21ParseFindParents(&x); + p21Init(&s, ctx); + for(i=0; inNode ); + if( argc==2 ){ + const char *zPath = (const char*)sqlite3_value_text(argv[1]); + pNode = p21Lookup(p, zPath, 0, ctx); + }else{ + pNode = p->aNode; + } + if( pNode==0 ){ + return; + } + if( pNode->eType==P21_LIST ){ + assert( (pNode->jnFlags & PNODE_APPEND)==0 ); + for(i=1; i<=pNode->n; n++){ + i += p21NodeSize(&pNode[i]); + } + } + sqlite3_result_int64(ctx, n); +} + +/* +** p21_extract(P21, PATH, ...) +** +** Return the element described by PATH. Return NULL if there is no +** PATH element. If there are multiple PATHs, then return a P21 array +** with the result from each path. Throw an error if the P21 or any PATH +** is malformed. +*/ +static void p21ExtractFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse *p; /* The parse */ + P21Node *pNode; + const char *zPath; + P21String jx; + int i; + + if( argc<2 ) return; + p = p21ParseCached(ctx, argv, ctx); + if( p==0 ) return; + p21Init(&jx, ctx); + p21AppendChar(&jx, '['); + for(i=1; inErr ) break; + if( argc>2 ){ + p21AppendSeparator(&jx); + if( pNode ){ + p21RenderNode(pNode, &jx, 0); + }else{ + p21AppendRaw(&jx, "null", 4); + } + }else if( pNode ){ + p21Return(pNode, ctx, 0); + } + } + if( argc>2 && i==argc ){ + p21AppendChar(&jx, ']'); + p21Result(&jx); + sqlite3_result_subtype(ctx, P21_SUBTYPE); + } + p21Reset(&jx); +} + +#if 0 +/* TODO: a MergeRecord function could be useful + */ +static P21Node *p21MergePatch( + P21Parse *pParse, /* The P21 parser that contains the TARGET */ + u32 iTarget, /* Node of the TARGET in pParse */ + P21Node *pPatch /* The PATCH */ +){ + u32 i, j; + u32 iRoot; + P21Node *pTarget; + if( pPatch->eType!=P21_RECORD ){ + return pPatch; + } + assert( iTargetnNode ); + pTarget = &pParse->aNode[iTarget]; + assert( (pPatch->jnFlags & PNODE_APPEND)==0 ); + if( pTarget->eType!=P21_RECORD ){ + p21RemoveAllNulls(pPatch); + return pPatch; + } + iRoot = iTarget; + for(i=1; in; i += p21NodeSize(&pPatch[i+1])+1){ + u32 nKey; + const char *zKey; + assert( pPatch[i].eType==P21_STRING ); + assert( pPatch[i].jnFlags & PNODE_LABEL ); + nKey = pPatch[i].n; + zKey = pPatch[i].u.zJContent; + assert( (pPatch[i].jnFlags & PNODE_RAW)==0 ); + for(j=1; jn; j += p21NodeSize(&pTarget[j+1])+1 ){ + assert( pTarget[j].eType==P21_STRING ); + assert( pTarget[j].jnFlags & PNODE_LABEL ); + assert( (pPatch[i].jnFlags & PNODE_RAW)==0 ); + if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ + if( pTarget[j+1].jnFlags & (PNODE_REMOVE|PNODE_PATCH) ) break; + if( pPatch[i+1].eType==P21_EMPTY ){ + pTarget[j+1].jnFlags |= PNODE_REMOVE; + }else{ + P21Node *pNew = p21MergePatch(pParse, iTarget+j+1, &pPatch[i+1]); + if( pNew==0 ) return 0; + pTarget = &pParse->aNode[iTarget]; + if( pNew!=&pTarget[j+1] ){ + pTarget[j+1].u.pPatch = pNew; + pTarget[j+1].jnFlags |= PNODE_PATCH; + } + } + break; + } + } + if( j>=pTarget->n && pPatch[i+1].eType!=P21_EMPTY ){ + int iStart, iPatch; + iStart = p21ParseAddNode(pParse, P21_RECORD, 2, 0); + p21ParseAddNode(pParse, P21_STRING, nKey, zKey); + iPatch = p21ParseAddNode(pParse, P21_TRUE, 0, 0); + if( pParse->oom ) return 0; + p21RemoveAllNulls(pPatch); + pTarget = &pParse->aNode[iTarget]; + pParse->aNode[iRoot].jnFlags |= PNODE_APPEND; + pParse->aNode[iRoot].u.iAppend = iStart - iRoot; + iRoot = iStart; + pParse->aNode[iPatch].jnFlags |= PNODE_PATCH; + pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; + } + } + return pTarget; +} + + +/* +** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a P21 +** object that is the result of running the RFC 7396 MergePatch() algorithm +** on the two arguments. +*/ +static void p21PatchFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse x; /* The P21 that is being patched */ + P21Parse y; /* The patch */ + P21Node *pResult; /* The result of the merge */ + + UNUSED_PARAM(argc); + if( p21Parse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + if( p21Parse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ + p21ParseReset(&x); + return; + } + pResult = p21MergePatch(&x, 0, y.aNode); + assert( pResult!=0 || x.oom ); + if( pResult ){ + p21ReturnP21(pResult, ctx, 0); + }else{ + sqlite3_result_error_nomem(ctx); + } + p21ParseReset(&x); + p21ParseReset(&y); +} +#endif + +/* +** Implementation of the p21_object(NAME,VALUE,...) function. Return a P21 +** object that contains all name/value given in arguments. Or if any name +** is not a string or if any value is a BLOB, throw an error. +*/ +static void p21ObjectFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int i; + P21String jx; + const char *z; + u32 n; + + if( argc&1 ){ + sqlite3_result_error(ctx, "p21_object() requires an even number " + "of arguments", -1); + return; + } + p21Init(&jx, ctx); + p21AppendChar(&jx, '{'); + for(i=0; ijnFlags |= PNODE_REMOVE; + } + if( (x.aNode[0].jnFlags & PNODE_REMOVE)==0 ){ + p21ReturnP21(x.aNode, ctx, 0); + } +remove_done: + p21ParseReset(&x); +} + +/* +** p21_replace(P21, PATH, VALUE, ...) +** +** Replace the value at PATH with VALUE. If PATH does not already exist, +** this routine is a no-op. If P21 or PATH is malformed, throw an error. +*/ +static void p21ReplaceFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse x; /* The parse */ + P21Node *pNode; + const char *zPath; + u32 i; + + if( argc<1 ) return; + if( (argc&1)==0 ) { + p21WrongNumArgs(ctx, "replace"); + return; + } + if( p21Parse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + assert( x.nNode ); + for(i=1; i<(u32)argc; i+=2){ + zPath = (const char*)sqlite3_value_text(argv[i]); + pNode = p21Lookup(&x, zPath, 0, ctx); + if( x.nErr ) goto replace_err; + if( pNode ){ + pNode->jnFlags |= (u8)PNODE_REPLACE; + pNode->u.iReplace = i + 1; + } + } + if( x.aNode[0].jnFlags & PNODE_REPLACE ){ + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); + }else{ + p21ReturnP21(x.aNode, ctx, argv); + } +replace_err: + p21ParseReset(&x); +} + +/* +** p21_set(P21, PATH, VALUE, ...) +** +** Set the value at PATH to VALUE. Create the PATH if it does not already +** exist. Overwrite existing values that do exist. +** If P21 or PATH is malformed, throw an error. +** +** p21_insert(P21, PATH, VALUE, ...) +** +** Create PATH and initialize it to VALUE. If PATH already exists, this +** routine is a no-op. If P21 or PATH is malformed, throw an error. +*/ +static void p21SetFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse x; /* The parse */ + P21Node *pNode; + const char *zPath; + u32 i; + int bApnd; + int bIsSet = *(int*)sqlite3_user_data(ctx); + + if( argc<1 ) return; + if( (argc&1)==0 ) { + p21WrongNumArgs(ctx, bIsSet ? "set" : "insert"); + return; + } + if( p21Parse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + assert( x.nNode ); + for(i=1; i<(u32)argc; i+=2){ + zPath = (const char*)sqlite3_value_text(argv[i]); + bApnd = 0; + pNode = p21Lookup(&x, zPath, &bApnd, ctx); + if( x.oom ){ + sqlite3_result_error_nomem(ctx); + goto p21SetDone; + }else if( x.nErr ){ + goto p21SetDone; + }else if( pNode && (bApnd || bIsSet) ){ + pNode->jnFlags |= (u8)PNODE_REPLACE; + pNode->u.iReplace = i + 1; + } + } + if( x.aNode[0].jnFlags & PNODE_REPLACE ){ + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); + }else{ + p21ReturnP21(x.aNode, ctx, argv); + } +p21SetDone: + p21ParseReset(&x); +} + +/* +** p21_type(P21) +** p21_type(P21, PATH) +** +** Return the top-level "type" of a P21 string. Throw an error if +** either the P21 or PATH inputs are not well-formed. +*/ +static void p21TypeFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse *p; /* The parse */ + const char *zPath; + P21Node *pNode; + + p = p21ParseCached(ctx, argv, ctx); + if( p==0 ) return; + if( argc==2 ){ + zPath = (const char*)sqlite3_value_text(argv[1]); + pNode = p21Lookup(p, zPath, 0, ctx); + }else{ + pNode = p->aNode; + } + if( pNode ){ + sqlite3_result_text(ctx, p21Type[pNode->eType], -1, SQLITE_STATIC); + } +} + +/* +** p21_valid(P21) +** +** Return 1 if P21 is a well-formed P21 string according to RFC-7159. +** Return 0 otherwise. +*/ +static void p21ValidFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse *p; /* The parse */ + UNUSED_PARAM(argc); + p = p21ParseCached(ctx, argv, 0); + sqlite3_result_int(ctx, p!=0); +} + + +/**************************************************************************** +** Aggregate SQL function implementations +****************************************************************************/ +/* +** p21_group_array(VALUE) +** +** Return a P21 array composed of all values in the aggregate. +*/ +static void p21ArrayStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21String *pStr; + UNUSED_PARAM(argc); + pStr = (P21String*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + if( pStr->zBuf==0 ){ + p21Init(pStr, ctx); + p21AppendChar(pStr, '['); + }else if( pStr->nUsed>1 ){ + p21AppendChar(pStr, ','); + pStr->pCtx = ctx; + } + p21AppendValue(pStr, argv[0]); + } +} +static void p21ArrayCompute(sqlite3_context *ctx, int isFinal){ + P21String *pStr; + pStr = (P21String*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + pStr->pCtx = ctx; + p21AppendChar(pStr, ']'); + if( pStr->bErr ){ + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); + assert( pStr->bStatic ); + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + pStr->nUsed--; + } + }else{ + sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, P21_SUBTYPE); +} +static void p21ArrayValue(sqlite3_context *ctx){ + p21ArrayCompute(ctx, 0); +} +static void p21ArrayFinal(sqlite3_context *ctx){ + p21ArrayCompute(ctx, 1); +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** This method works for both p21_group_array() and p21_group_object(). +** It works by removing the first element of the group by searching forward +** to the first comma (",") that is not within a string and deleting all +** text through that comma. +*/ +static void p21GroupInverse( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + unsigned int i; + int inStr = 0; + int nNest = 0; + char *z; + char c; + P21String *pStr; + UNUSED_PARAM(argc); + UNUSED_PARAM(argv); + pStr = (P21String*)sqlite3_aggregate_context(ctx, 0); +#ifdef NEVER + /* pStr is always non-NULL since p21ArrayStep() or p21ObjectStep() will + ** always have been called to initalize it */ + if( NEVER(!pStr) ) return; +#endif + z = pStr->zBuf; + for(i=1; (c = z[i])!=',' || inStr || nNest; i++){ + if( i>=pStr->nUsed ){ + pStr->nUsed = 1; + return; + } + if( c=='"' ){ + inStr = !inStr; + }else if( c=='\\' ){ + i++; + }else if( !inStr ){ + if( c=='{' || c=='[' ) nNest++; + if( c=='}' || c==']' ) nNest--; + } + } + pStr->nUsed -= i; + memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); +} +#else +# define p21GroupInverse 0 +#endif + + +/* +** p21_group_obj(NAME,VALUE) +** +** Return a P21 object composed of all names and values in the aggregate. +*/ +static void p21ObjectStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21String *pStr; + const char *z; + u32 n; + UNUSED_PARAM(argc); + pStr = (P21String*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + if( pStr->zBuf==0 ){ + p21Init(pStr, ctx); + p21AppendChar(pStr, '{'); + }else if( pStr->nUsed>1 ){ + p21AppendChar(pStr, ','); + pStr->pCtx = ctx; + } + z = (const char*)sqlite3_value_text(argv[0]); + n = (u32)sqlite3_value_bytes(argv[0]); + p21AppendString(pStr, z, n); + p21AppendChar(pStr, ':'); + p21AppendValue(pStr, argv[1]); + } +} +static void p21ObjectCompute(sqlite3_context *ctx, int isFinal){ + P21String *pStr; + pStr = (P21String*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + p21AppendChar(pStr, '}'); + if( pStr->bErr ){ + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); + assert( pStr->bStatic ); + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + pStr->nUsed--; + } + }else{ + sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, P21_SUBTYPE); +} +static void p21ObjectValue(sqlite3_context *ctx){ + p21ObjectCompute(ctx, 0); +} +static void p21ObjectFinal(sqlite3_context *ctx){ + p21ObjectCompute(ctx, 1); +} + + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/**************************************************************************** +** The p21_each virtual table +****************************************************************************/ +typedef struct P21EachCursor P21EachCursor; +struct P21EachCursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + u32 iRowid; /* The rowid */ + u32 iBegin; /* The first node of the scan */ + u32 i; /* Index in sParse.aNode[] of current row */ + u32 iEnd; /* EOF when i equals or exceeds this value */ + u8 eType; /* Type of top-level element */ + char *zP21; /* Input P21 */ + char *zRoot; /* Path by which to filter zP21 */ + P21Parse sParse; /* Parse of the input P21 */ +}; + +/* Constructor for the p21_each virtual table */ +static int p21EachConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + sqlite3_vtab *pNew; + int rc; + +/* Column numbers */ +#define PEACH_KEY 0 +#define PEACH_VALUE 1 +#define PEACH_TYPE 2 +#define PEACH_ATOM 3 +#define PEACH_ID 4 +#define PEACH_PARENT 5 +#define PEACH_FULLKEY 6 +#define PEACH_PATH 7 +/* The xBestIndex method assumes that the P21 and ROOT columns are +** the last two columns in the table. Should this ever changes, be +** sure to update the xBestIndex method. */ +#define PEACH_P21 8 +#define PEACH_ROOT 9 + + UNUSED_PARAM(pzErr); + UNUSED_PARAM(argv); + UNUSED_PARAM(argc); + UNUSED_PARAM(pAux); + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," + "p21 HIDDEN,root HIDDEN)"); + if( rc==SQLITE_OK ){ + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + } + return rc; +} + +/* destructor for p21_each virtual table */ +static int p21EachDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* constructor for a P21EachCursor object for p21_each(). */ +static int p21EachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + P21EachCursor *pCur; + + UNUSED_PARAM(p); + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* Reset a P21EachCursor back to its original state. Free any memory +** held. */ +static void p21EachCursorReset(P21EachCursor *p){ + sqlite3_free(p->zP21); + sqlite3_free(p->zRoot); + p21ParseReset(&p->sParse); + p->iRowid = 0; + p->i = 0; + p->iEnd = 0; + p->eType = 0; + p->zP21 = 0; + p->zRoot = 0; +} + +/* Destructor for a p21EachCursor object */ +static int p21EachClose(sqlite3_vtab_cursor *cur){ + P21EachCursor *p = (P21EachCursor*)cur; + p21EachCursorReset(p); + sqlite3_free(cur); + return SQLITE_OK; +} + +/* Return TRUE if the p21EachCursor object has been advanced off the end +** of the P21 object */ +static int p21EachEof(sqlite3_vtab_cursor *cur){ + P21EachCursor *p = (P21EachCursor*)cur; + return p->i >= p->iEnd; +} + +/* Advance the cursor to the next element for p21_tree() */ +static int p21EachNext(sqlite3_vtab_cursor *cur){ + P21EachCursor *p = (P21EachCursor*)cur; + switch( p->eType ){ + case P21_RECORD: + case P21_LIST: { + p->i += p21NodeSize(&p->sParse.aNode[p->i]); + p->iRowid++; + break; + } + default: { + p->i = p->iEnd; + break; + } + } + return SQLITE_OK; +} + +/* Append the name of the path for element i to pStr +*/ +static void p21EachComputePath( + P21EachCursor *p, /* The cursor */ + P21String *pStr, /* Write the path here */ + u32 i /* Path to this element */ +){ + P21Node *pNode, *pUp; + u32 iUp; + if( i==0 ){ + p21AppendChar(pStr, '$'); + return; + } + iUp = p->sParse.aUp[i]; + p21EachComputePath(p, pStr, iUp); + pNode = &p->sParse.aNode[i]; + pUp = &p->sParse.aNode[iUp]; + if( pUp->eType==P21_LIST ){ + p21Printf(30, pStr, "[%d]", pUp->u.iKey); + }else{ + assert( pUp->eType==P21_RECORD ); + if( (pNode->jnFlags & PNODE_LABEL)==0 ) pNode--; + assert( pNode->eType==P21_STRING ); + assert( pNode->jnFlags & PNODE_LABEL ); + p21Printf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); + } +} + +/* Return the value of a column */ +static int p21EachColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + P21EachCursor *p = (P21EachCursor*)cur; + P21Node *pThis = &p->sParse.aNode[p->i]; + switch( i ){ + case PEACH_KEY: { + if( p->i==0 ) break; + if( p->eType==P21_RECORD ){ + p21Return(pThis, ctx, 0); + }else if( p->eType==P21_LIST ){ + u32 iKey; + iKey = p->iRowid; + sqlite3_result_int64(ctx, (sqlite3_int64)iKey); + } + break; + } + case PEACH_VALUE: { + if( pThis->jnFlags & PNODE_LABEL ) pThis++; + p21Return(pThis, ctx, 0); + break; + } + case PEACH_TYPE: { + if( pThis->jnFlags & PNODE_LABEL ) pThis++; + sqlite3_result_text(ctx, p21Type[pThis->eType], -1, SQLITE_STATIC); + break; + } + case PEACH_ATOM: { + if( pThis->jnFlags & PNODE_LABEL ) pThis++; + if( pThis->eType>=P21_LIST ) break; + p21Return(pThis, ctx, 0); + break; + } + case PEACH_ID: { + sqlite3_result_int64(ctx, + (sqlite3_int64)p->i + ((pThis->jnFlags & PNODE_LABEL)!=0)); + break; + } + case PEACH_FULLKEY: { + P21String x; + p21Init(&x, ctx); + if( p->zRoot ){ + p21AppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); + }else{ + p21AppendChar(&x, '$'); + } + if( p->eType==P21_LIST ){ + p21Printf(30, &x, "[%d]", p->iRowid); + }else if( p->eType==P21_RECORD ){ + p21Printf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); + } + p21Result(&x); + break; + } + case PEACH_PATH: + default: { + const char *zRoot = p->zRoot; + if( zRoot==0 ) zRoot = "$"; + sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); + break; + } + case PEACH_P21: { + assert( i==PEACH_P21 ); + sqlite3_result_text(ctx, p->sParse.zP21, -1, SQLITE_STATIC); + break; + } + } + return SQLITE_OK; +} + +/* Return the current rowid value */ +static int p21EachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + P21EachCursor *p = (P21EachCursor*)cur; + *pRowid = p->iRowid; + return SQLITE_OK; +} + +/* The query strategy is to look for an equality constraint on the p21 +** column. Without such a constraint, the table cannot operate. idxNum is +** 1 if the constraint is found, 3 if the constraint and zRoot are found, +** and 0 otherwise. +*/ +static int p21EachBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop counter or computed array index */ + int aIdx[2]; /* Index of constraints for P21 and ROOT */ + int unusableMask = 0; /* Mask of unusable P21 and ROOT constraints */ + int idxMask = 0; /* Mask of usable == constraints P21 and ROOT */ + const struct sqlite3_index_constraint *pConstraint; + + /* This implementation assumes that P21 and ROOT are the last two + ** columns in the table */ + assert( PEACH_ROOT == PEACH_P21+1 ); + UNUSED_PARAM(tab); + aIdx[0] = aIdx[1] = -1; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + int iCol; + int iMask; + if( pConstraint->iColumn < PEACH_P21 ) continue; + iCol = pConstraint->iColumn - PEACH_P21; + assert( iCol==0 || iCol==1 ); + iMask = 1 << iCol; + if( pConstraint->usable==0 ){ + unusableMask |= iMask; + }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + aIdx[iCol] = i; + idxMask |= iMask; + } + } + if( (unusableMask & ~idxMask)!=0 ){ + /* If there are any unusable constraints on P21 or ROOT, then reject + ** this entire plan */ + return SQLITE_CONSTRAINT; + } + if( aIdx[0]<0 ){ + /* No P21 input. Leave estimatedCost at the huge value that it was + ** initialized to to discourage the query planner from selecting this + ** plan. */ + pIdxInfo->idxNum = 0; + }else{ + pIdxInfo->estimatedCost = 1.0; + i = aIdx[0]; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + if( aIdx[1]<0 ){ + pIdxInfo->idxNum = 1; /* Only P21 supplied. Plan 1 */ + }else{ + i = aIdx[1]; + pIdxInfo->aConstraintUsage[i].argvIndex = 2; + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->idxNum = 3; /* Both P21 and ROOT are supplied. Plan 3 */ + } + } + return SQLITE_OK; +} + +/* Start a search on a new P21 string */ +static int p21EachFilter( + sqlite3_vtab_cursor *cur, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + P21EachCursor *p = (P21EachCursor*)cur; + const char *z; + const char *zRoot = 0; + sqlite3_int64 n; + + UNUSED_PARAM(idxStr); + UNUSED_PARAM(argc); + p21EachCursorReset(p); + if( idxNum==0 ) return SQLITE_OK; + z = (const char*)sqlite3_value_text(argv[0]); + if( z==0 ) return SQLITE_OK; + n = sqlite3_value_bytes(argv[0]); + p->zP21 = sqlite3_malloc64( n+1 ); + if( p->zP21==0 ) return SQLITE_NOMEM; + memcpy(p->zP21, z, (size_t)n+1); + if( p21Parse(&p->sParse, 0, p->zP21) ){ + int rc = SQLITE_NOMEM; + if( p->sParse.oom==0 ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed P21"); + if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; + } + p21EachCursorReset(p); + return rc; + }else{ + P21Node *pNode = 0; + if( idxNum==3 ){ + const char *zErr = 0; + zRoot = (const char*)sqlite3_value_text(argv[1]); + if( zRoot==0 ) return SQLITE_OK; + n = sqlite3_value_bytes(argv[1]); + p->zRoot = sqlite3_malloc64( n+1 ); + if( p->zRoot==0 ) return SQLITE_NOMEM; + memcpy(p->zRoot, zRoot, (size_t)n+1); + if( zRoot[0]!='$' ){ + zErr = zRoot; + }else{ + pNode = p21LookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); + } + if( zErr ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = p21PathSyntaxError(zErr); + p21EachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + }else if( pNode==0 ){ + return SQLITE_OK; + } + }else{ + pNode = p->sParse.aNode; + } + p->iBegin = p->i = (int)(pNode - p->sParse.aNode); + p->eType = pNode->eType; + if( p->eType>=P21_LIST ){ + pNode->u.iKey = 0; + p->iEnd = p->i + pNode->n + 1; + p->i++; + }else{ + p->iEnd = p->i+1; + } + } + return SQLITE_OK; +} + +/* The methods of the p21_each virtual table */ +static sqlite3_module p21EachModule = { + 0, /* iVersion */ + 0, /* xCreate */ + p21EachConnect, /* xConnect */ + p21EachBestIndex, /* xBestIndex */ + p21EachDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + p21EachOpenEach, /* xOpen - open a cursor */ + p21EachClose, /* xClose - close a cursor */ + p21EachFilter, /* xFilter - configure scan constraints */ + p21EachNext, /* xNext - advance a cursor */ + p21EachEof, /* xEof - check for end of scan */ + p21EachColumn, /* xColumn - read data */ + p21EachRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0 /* xShadowName */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/**************************************************************************** +** The following routines are the only publically visible identifiers in this +** file. Call the following routines in order to register the various SQL +** functions and the virtual table implemented by this file. +****************************************************************************/ + +int sqlite3P21sqlInit(sqlite3 *db){ + int rc = SQLITE_OK; + unsigned int i; + static const struct { + const char *zName; + int nArg; + int flag; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } aFunc[] = { + { "p21", 1, 0, p21RemoveFunc }, + { "p21_array", -1, 0, p21ArrayFunc }, + { "p21_array_length", 1, 0, p21ArrayLengthFunc }, + { "p21_array_length", 2, 0, p21ArrayLengthFunc }, + { "p21_extract", -1, 0, p21ExtractFunc }, + { "p21_insert", -1, 0, p21SetFunc }, + { "p21_object", -1, 0, p21ObjectFunc }, +#if 0 + { "p21_patch", 2, 0, p21PatchFunc }, +#endif + { "p21_quote", 1, 0, p21QuoteFunc }, + { "p21_remove", -1, 0, p21RemoveFunc }, + { "p21_replace", -1, 0, p21ReplaceFunc }, + { "p21_set", -1, 1, p21SetFunc }, + { "p21_type", 1, 0, p21TypeFunc }, + { "p21_type", 2, 0, p21TypeFunc }, + { "p21_valid", 1, 0, p21ValidFunc }, + +#if SQLITE_DEBUG + /* DEBUG and TESTING functions */ + { "p21_parse", 1, 0, p21ParseFunc }, + { "p21_test1", 1, 0, p21Test1Func }, +#endif + }; + static const struct { + const char *zName; + int nArg; + void (*xStep)(sqlite3_context*,int,sqlite3_value**); + void (*xFinal)(sqlite3_context*); + void (*xValue)(sqlite3_context*); + } aAgg[] = { + { "p21_group_array", 1, + p21ArrayStep, p21ArrayFinal, p21ArrayValue }, + { "p21_group_object", 2, + p21ObjectStep, p21ObjectFinal, p21ObjectValue }, + }; +#ifndef SQLITE_OMIT_VIRTUALTABLE + static const struct { + const char *zName; + sqlite3_module *pModule; + } aMod[] = { + { "p21_each", &p21EachModule }, + }; +#endif + static const int enc = + SQLITE_UTF8 | + SQLITE_DETERMINISTIC | + SQLITE_INNOCUOUS; + for(i=0; i +#include +#include +#include + +/* Mark a function parameter as unused, to suppress nuisance compiler +** warnings. */ +#ifndef UNUSED_PARAM +# define UNUSED_PARAM(X) (void)(X) +#endif + +#ifndef LARGEST_INT64 +# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) +#endif + +/* +** Versions of isspace(), isalnum() and isdigit() to which it is safe +** to pass signed char values. +*/ +#ifdef sqlite3Isdigit + /* Use the SQLite core versions if this routine is part of the + ** SQLite amalgamation */ +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) +#else + /* Use the standard library for separate compilation */ +#include /* amalgamator: keep */ +# define safe_isdigit(x) isdigit((unsigned char)(x)) +# define safe_isalnum(x) isalnum((unsigned char)(x)) +# define safe_isxdigit(x) isxdigit((unsigned char)(x)) +#endif + +/* +** Growing our own isspace() routine this way is twice as fast as +** the library isspace() function, resulting in a 7% overall performance +** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). +*/ +static const char p21IsSpace[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +#define safe_isspace(x) (p21IsSpace[(unsigned char)x]) + +#ifndef SQLITE_AMALGAMATION + /* Unsigned integer types. These are already defined in the sqliteInt.h, + ** but the definitions need to be repeated for separate compilation. */ + typedef sqlite3_uint64 u64; + typedef unsigned int u32; + typedef unsigned short int u16; + typedef unsigned char u8; +#endif + +/* some C implementations don't have these? (inttypes.h / stdint.h) */ +#ifndef UINT16_WIDTH +# define UINT16_WIDTH 16 +#endif +#ifndef UINT16_MAX +# define UINT16_MAX 65535 +#endif + +/* Objects */ +typedef struct P21String P21String; +typedef struct P21Node P21Node; +typedef struct P21Parse P21Parse; + +/* An instance of this object represents a P21 parameter string +** under construction. Really, this is a generic string accumulator +** that can be and is used to create strings other than JSON (here P21!). +*/ +struct P21String { + sqlite3_context *pCtx; /* Function context - put error messages here */ + char *zBuf; /* Append P21 content here */ + u64 nAlloc; /* Bytes of storage available in zBuf[] */ + u64 nUsed; /* Bytes of zBuf[] currently used */ + u8 bStatic; /* True if zBuf is static space */ + u8 bErr; /* True if an error has been encountered */ + char zSpace[100]; /* Initial static space */ +}; + +#define P21_EMPTY 0x1 /* optional attribute not provided : '$' */ +#define P21_DERIVED 0x2 /* derived attribute not provided : '*' */ +#define P21_ENUMERATION 0x3 /* (also) includes boolean and logical values */ +#define P21_INTEGER 0x4 +#define P21_REAL 0x5 +#define P21_STRING 0x6 +#define P21_BINARY 0x7 +#define P21_EID 0x8 /* entity_instance_name */ +#define P21_LIST 0x9 +#define P21_RECORD 0xA /* simple_record */ + +#define P21_SUBTYPE 80 /* Ascii for "P" */ + + +/* +** Names of the various P21 types: +*/ +static const char * const p21Type[] = { + "", + "empty", "derived", "enumeration", "integer", "real", + "string", "binary", "eid", "list", "record" +}; + +/* Bit values for the P21Node.jnFlag field +*/ +#define PNODE_RAW 0x01 /* Content is raw, not P21 encoded */ +#define PNODE_ESCAPE 0x02 /* Content is text with \ escapes */ +#define PNODE_REMOVE 0x04 /* Do not output */ +#define PNODE_REPLACE 0x08 /* Replace with P21Node.u.iReplace */ +#define PNODE_PATCH 0x10 /* Patch with P21Node.u.pPatch */ +#define PNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ +#define PNODE_LABEL 0x40 /* Is a label of an object */ + + +/* A single node of parsed P21 params +*/ +struct P21Node { + u8 eType; /* One of the P21_ type values */ + u8 jnFlags; /* P21Node flags */ + u16 n_kw; /* store the KEYWORD length */ + u32 n; /* Bytes of content, or number of sub-nodes */ + union { + const char *zJContent; /* Content for INT, REAL, and STRING */ + u32 iAppend; /* More terms for ARRAY and OBJECT */ + u32 iKey; /* Key for ARRAY objects in p21_tree() */ + u32 iReplace; /* Replacement content for PNODE_REPLACE */ + P21Node *pPatch; /* Node chain of patch for PNODE_PATCH */ + } u; +}; + +/* A completely parsed P21 string +*/ +struct P21Parse { + u32 nNode; /* Number of slots of aNode[] used */ + u32 nAlloc; /* Number of slots of aNode[] allocated */ + P21Node *aNode; /* Array of nodes containing the parse */ + const char *zP21; /* Original P21 string */ + u32 *aUp; /* Index of parent of each node */ + u8 oom; /* Set to true if out of memory */ + u8 nErr; /* Number of errors seen */ + u16 iDepth; /* Nesting depth */ + int nP21; /* Length of the zP21 string in bytes */ + u32 iHold; /* Replace cache line with the lowest iHold value */ +}; + +/* +** Maximum nesting depth of P21 for this implementation. +*/ +#define P21_MAX_DEPTH 20 + +/************************************************************************** +** Utility routines for dealing with P21String objects +**************************************************************************/ + +/* Set the P21String object to an empty string +*/ +static void p21Zero(P21String *p){ + p->zBuf = p->zSpace; + p->nAlloc = sizeof(p->zSpace); + p->nUsed = 0; + p->bStatic = 1; +} + +/* Initialize the P21String object +*/ +static void p21Init(P21String *p, sqlite3_context *pCtx){ + p->pCtx = pCtx; + p->bErr = 0; + p21Zero(p); +} + + +/* Free all allocated memory and reset the P21String object back to its +** initial state. +*/ +static void p21Reset(P21String *p){ + if( !p->bStatic ) sqlite3_free(p->zBuf); + p21Zero(p); +} + + +/* Report an out-of-memory (OOM) condition +*/ +static void p21Oom(P21String *p){ + p->bErr = 1; + sqlite3_result_error_nomem(p->pCtx); + p21Reset(p); +} + +/* Enlarge p->zBuf so that it can hold at least N more bytes. +** Return zero on success. Return non-zero on an OOM error +*/ +static int p21Grow(P21String *p, u32 N){ + u64 nTotal = NnAlloc ? p->nAlloc*2 : p->nAlloc+N+10; + char *zNew; + if( p->bStatic ){ + if( p->bErr ) return 1; + zNew = sqlite3_malloc64(nTotal); + if( zNew==0 ){ + p21Oom(p); + return SQLITE_NOMEM; + } + memcpy(zNew, p->zBuf, (size_t)p->nUsed); + p->zBuf = zNew; + p->bStatic = 0; + }else{ + zNew = sqlite3_realloc64(p->zBuf, nTotal); + if( zNew==0 ){ + p21Oom(p); + return SQLITE_NOMEM; + } + p->zBuf = zNew; + } + p->nAlloc = nTotal; + return SQLITE_OK; +} + +/* Append N bytes from zIn onto the end of the P21String string. +*/ +static void p21AppendRaw(P21String *p, const char *zIn, u32 N){ + if( (N+p->nUsed >= p->nAlloc) && p21Grow(p,N)!=0 ) return; + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; +} + +/* Append formatted text (not to exceed N bytes) to the P21String. +*/ +static void p21Printf(int N, P21String *p, const char *zFormat, ...){ + va_list ap; + if( (p->nUsed + N >= p->nAlloc) && p21Grow(p, N) ) return; + va_start(ap, zFormat); + sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); + va_end(ap); + p->nUsed += (int)strlen(p->zBuf+p->nUsed); +} + +/* Append a single character +*/ +static void p21AppendChar(P21String *p, char c){ + if( p->nUsed>=p->nAlloc && p21Grow(p,1)!=0 ) return; + p->zBuf[p->nUsed++] = c; +} + +/* Append a comma separator to the output buffer, if the previous +** character is not '[' or '{'. +*/ +static void p21AppendSeparator(P21String *p){ + char c; + if( p->nUsed==0 ) return; + c = p->zBuf[p->nUsed-1]; + if( c!='(' ) p21AppendChar(p, ','); +} + +/* Append the N-byte string in zIn to the end of the P21String string +** under construction. Enclose the string in '...' and escape +** any double-quotes or backslash characters contained within the +** string. +*/ +static void p21AppendString(P21String *p, const char *zIn, u32 N){ + u32 i; + if( (N+p->nUsed+2 >= p->nAlloc) && p21Grow(p,N+2)!=0 ) return; + p->zBuf[p->nUsed++] = '\''; + for(i=0; inUsed+N+3-i > p->nAlloc) && p21Grow(p,N+3-i)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + }else if( c<=0x1f ){ + static const char aSpecial[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + assert( sizeof(aSpecial)==32 ); + assert( aSpecial['\b']=='b' ); + assert( aSpecial['\f']=='f' ); + assert( aSpecial['\n']=='n' ); + assert( aSpecial['\r']=='r' ); + assert( aSpecial['\t']=='t' ); + if( aSpecial[c] ){ + c = aSpecial[c]; + goto p21_simple_escape; + } + if( (p->nUsed+N+7+i > p->nAlloc) && p21Grow(p,N+7-i)!=0 ) return; + p->zBuf[p->nUsed++] = '\\'; + p->zBuf[p->nUsed++] = 'u'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0'; + p->zBuf[p->nUsed++] = '0' + (c>>4); + c = "0123456789abcdef"[c&0xf]; + } + p->zBuf[p->nUsed++] = c; + } + p->zBuf[p->nUsed++] = '\''; + assert( p->nUsednAlloc ); +} + +/* +** Append a function parameter value to the P21 string under +** construction. +*/ +static void p21AppendValue( + P21String *p, /* Append to this P21 string */ + sqlite3_value *pValue /* Value to append */ +){ + switch( sqlite3_value_type(pValue) ){ + case SQLITE_NULL: { + p21AppendRaw(p, "$", 1); + break; + } + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + const char *z = (const char*)sqlite3_value_text(pValue); + /* TODO: confirm format is valid */ + u32 n = (u32)sqlite3_value_bytes(pValue); + p21AppendRaw(p, z, n); + break; + } + case SQLITE_TEXT: { + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + if( sqlite3_value_subtype(pValue)==P21_SUBTYPE ){ + p21AppendRaw(p, z, n); + }else{ + p21AppendString(p, z, n); + } + break; + } + default: { + if( p->bErr==0 ){ + sqlite3_result_error(p->pCtx, "P21 cannot hold BLOB values", -1); + p->bErr = 2; + p21Reset(p); + } + break; + } + } +} + + +/* Make the P21 in p the result of the SQL function. +*/ +static void p21Result(P21String *p){ + if( p->bErr==0 ){ + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, + SQLITE_UTF8); + p21Zero(p); + } + assert( p->bStatic ); +} + +/************************************************************************** +** Utility routines for dealing with P21Node and P21Parse objects +**************************************************************************/ + +/* +** Return the number of consecutive P21Node slots need to represent +** the parsed P21 at pNode. The minimum answer is 1. For ARRAY and +** OBJECT types, the number might be larger. +** +** Appended elements are not counted. The value returned is the number +** by which the P21Node counter should increment in order to go to the +** next peer value. +*/ +static u32 p21NodeSize(P21Node *pNode){ + return pNode->eType < P21_LIST ? 1 : pNode->n + 1; +} + +/* +** Reclaim all memory allocated by a P21Parse object. But do not +** delete the P21Parse object itself. +*/ +static void p21ParseReset(P21Parse *pParse){ + sqlite3_free(pParse->aNode); + pParse->aNode = 0; + pParse->nNode = 0; + pParse->nAlloc = 0; + sqlite3_free(pParse->aUp); + pParse->aUp = 0; +} + +/* +** Free a P21Parse object that was obtained from sqlite3_malloc(). +*/ +static void p21ParseFree(P21Parse *pParse){ + p21ParseReset(pParse); + sqlite3_free(pParse); +} + +/* +** Convert the P21Node pNode into a pure P21 string and +** append to pOut. Subsubstructure is also included. Return +** the number of P21Node objects that are encoded. +*/ +static void p21RenderNode( + P21Node *pNode, /* The node to render */ + P21String *pOut, /* Write P21 here */ + sqlite3_value **aReplace /* Replacement values */ +){ + if( pNode->jnFlags & (PNODE_REPLACE|PNODE_PATCH) ){ + if( pNode->jnFlags & PNODE_REPLACE ){ + p21AppendValue(pOut, aReplace[pNode->u.iReplace]); + return; + } + pNode = pNode->u.pPatch; + } + switch( pNode->eType ){ + default: { + assert( pNode->eType==P21_EMPTY ); + p21AppendChar(pOut, '$'); + break; + } + case P21_ENUMERATION: { + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n); + break; + } + case P21_DERIVED: { + p21AppendChar(pOut, '*'); + break; + } + case P21_BINARY: { + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n); + break; + } + case P21_EID: { + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n); + break; + } + case P21_STRING: { + if( pNode->jnFlags & PNODE_RAW ){ + p21AppendString(pOut, pNode->u.zJContent, pNode->n); + break; + } + /* Fall through into the next case */ + } + case P21_REAL: + case P21_INTEGER: { + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n); + break; + } + case P21_LIST: { + u32 j = 1; + p21AppendChar(pOut, '('); + for(;;){ + while( j<=pNode->n ){ + if( (pNode[j].jnFlags & PNODE_REMOVE)==0 ){ + p21AppendSeparator(pOut); + p21RenderNode(&pNode[j], pOut, aReplace); + } + j += p21NodeSize(&pNode[j]); + } + if( (pNode->jnFlags & PNODE_APPEND)==0 ) break; + pNode = &pNode[pNode->u.iAppend]; + j = 1; + } + p21AppendChar(pOut, ')'); + break; + } + case P21_RECORD: { + u32 j = 1; + p21AppendRaw(pOut, pNode->u.zJContent, pNode->n_kw); + p21AppendChar(pOut, '('); + for(;;){ + while( j<= pNode->n ){ + if( (pNode[j].jnFlags & PNODE_REMOVE)==0 ){ + p21AppendSeparator(pOut); + p21RenderNode(&pNode[j], pOut, aReplace); + } + j += p21NodeSize(&pNode[j]); + } + if( (pNode->jnFlags & PNODE_APPEND)==0 ) break; + pNode = &pNode[pNode->u.iAppend]; + j = 1; + } + p21AppendChar(pOut, ')'); + break; + } + } +} + +/* +** Return a P21Node and all its descendents as a P21 string. +*/ +static void p21ReturnP21( + P21Node *pNode, /* Node to return */ + sqlite3_context *pCtx, /* Return value for this function */ + sqlite3_value **aReplace /* Array of replacement values */ +){ + P21String s; + p21Init(&s, pCtx); + p21RenderNode(pNode, &s, aReplace); + p21Result(&s); + sqlite3_result_subtype(pCtx, P21_SUBTYPE); +} + +/* +** Translate a single byte of Hex into an integer. +** This routine only works if h really is a valid hexadecimal +** character: 0..9a..fA..F +*/ +static u8 p21HexToInt(int h){ + assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#else + h += 9*(1&(h>>6)); +#endif + return (u8)(h & 0xf); +} + +/* +** Convert a 4-byte hex string into an integer +*/ +static u32 p21HexToInt4(const char *z){ + u32 v; + assert( safe_isxdigit(z[0]) ); + assert( safe_isxdigit(z[1]) ); + assert( safe_isxdigit(z[2]) ); + assert( safe_isxdigit(z[3]) ); + v = (p21HexToInt(z[0])<<12) + + (p21HexToInt(z[1])<<8) + + (p21HexToInt(z[2])<<4) + + p21HexToInt(z[3]); + return v; +} +/* +** Make the P21Node the return value of the function. +*/ +static void p21Return( + P21Node *pNode, /* Node to return */ + sqlite3_context *pCtx, /* Return value for this function */ + sqlite3_value **aReplace /* Array of replacement values */ +){ + switch( pNode->eType ){ + default: { + assert( pNode->eType==P21_EMPTY ); + sqlite3_result_null(pCtx); + break; + } + case P21_DERIVED: { + assert(0); + } + case P21_ENUMERATION: { + assert(0); + } + case P21_BINARY: { + assert(0); + } + case P21_EID: { + sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, SQLITE_TRANSIENT); + break; + } + case P21_INTEGER: { + sqlite3_int64 i = 0; + const char *z = pNode->u.zJContent; + if( z[0]=='-' ){ z++; } + while( z[0]>='0' && z[0]<='9' ){ + unsigned v = *(z++) - '0'; + if( i>=LARGEST_INT64/10 ){ + if( i>LARGEST_INT64/10 ) goto int_as_real; + if( z[0]>='0' && z[0]<='9' ) goto int_as_real; + if( v==9 ) goto int_as_real; + if( v==8 ){ + if( pNode->u.zJContent[0]=='-' ){ + sqlite3_result_int64(pCtx, SMALLEST_INT64); + goto int_done; + }else{ + goto int_as_real; + } + } + } + i = i*10 + v; + } + if( pNode->u.zJContent[0]=='-' ){ i = -i; } + sqlite3_result_int64(pCtx, i); + int_done: + break; + int_as_real: /* fall through to real */; + } + case P21_REAL: { + double r; +#ifdef SQLITE_AMALGAMATION + const char *z = pNode->u.zJContent; + sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); +#else + r = strtod(pNode->u.zJContent, 0); +#endif + sqlite3_result_double(pCtx, r); + break; + } + case P21_STRING: { +#if 0 /* Never happens because PNODE_RAW is only set by p21_set(), + ** p21_insert() and p21_replace() and those routines do not + ** call p21Return() */ + if( pNode->jnFlags & PNODE_RAW ){ + sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, + SQLITE_TRANSIENT); + }else +#endif + assert( (pNode->jnFlags & PNODE_RAW)==0 ); + if( (pNode->jnFlags & PNODE_ESCAPE)==0 ){ + /* P21 formatted without any backslash-escapes */ + sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, + SQLITE_TRANSIENT); + }else{ + /* Translate P21 formatted string into raw text */ + u32 i; + u32 n = pNode->n; + const char *z = pNode->u.zJContent; + char *zOut; + u32 j; + /* TODO: */ + assert(0); + zOut = sqlite3_malloc( n+1 ); + if( zOut==0 ){ + sqlite3_result_error_nomem(pCtx); + break; + } + for(i=1, j=0; i>6)); + zOut[j++] = 0x80 | (v&0x3f); + }else{ + u32 vlo; + if( (v&0xfc00)==0xd800 + && i>18); + zOut[j++] = 0x80 | ((v>>12)&0x3f); + zOut[j++] = 0x80 | ((v>>6)&0x3f); + zOut[j++] = 0x80 | (v&0x3f); + }else{ + zOut[j++] = 0xe0 | (v>>12); + zOut[j++] = 0x80 | ((v>>6)&0x3f); + zOut[j++] = 0x80 | (v&0x3f); + } + } + }else{ + if( c=='b' ){ + c = '\b'; + }else if( c=='f' ){ + c = '\f'; + }else if( c=='n' ){ + c = '\n'; + }else if( c=='r' ){ + c = '\r'; + }else if( c=='t' ){ + c = '\t'; + } + zOut[j++] = c; + } + } + } + zOut[j] = 0; + sqlite3_result_text(pCtx, zOut, j, sqlite3_free); + } + break; + } + case P21_LIST: + case P21_RECORD: { + p21ReturnP21(pNode, pCtx, aReplace); + break; + } + } +} + +/* Forward reference */ +static int p21ParseAddNode(P21Parse*,u32,u32,const char*); + +/* +** A macro to hint to the compiler that a function should not be +** inlined. +*/ +#if defined(__GNUC__) +# define P21_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) && _MSC_VER>=1310 +# define P21_NOINLINE __declspec(noinline) +#else +# define P21_NOINLINE +#endif + + +static P21_NOINLINE int p21ParseAddNodeExpand( + P21Parse *pParse, /* Append the node to this object */ + u32 eType, /* Node type */ + u32 n, /* Content size or sub-node count */ + const char *zContent /* Content */ +){ + u32 nNew; + P21Node *pNew; + assert( pParse->nNode>=pParse->nAlloc ); + if( pParse->oom ) return -1; + nNew = pParse->nAlloc*2 + 10; + pNew = sqlite3_realloc64(pParse->aNode, sizeof(P21Node)*nNew); + if( pNew==0 ){ + pParse->oom = 1; + return -1; + } + pParse->nAlloc = nNew; + pParse->aNode = pNew; + assert( pParse->nNodenAlloc ); + return p21ParseAddNode(pParse, eType, n, zContent); +} + +/* +** Create a new P21Node instance based on the arguments and append that +** instance to the P21Parse. Return the index in pParse->aNode[] of the +** new node, or -1 if a memory allocation fails. +*/ +static int p21ParseAddNode( + P21Parse *pParse, /* Append the node to this object */ + u32 eType, /* Node type */ + u32 n, /* Content size or sub-node count */ + const char *zContent /* Content */ +){ + P21Node *p; + if( pParse->nNode>=pParse->nAlloc ){ + return p21ParseAddNodeExpand(pParse, eType, n, zContent); + } + p = &pParse->aNode[pParse->nNode]; + p->eType = (u8)eType; + p->jnFlags = 0; + p->n = n; + p->u.zJContent = zContent; + return pParse->nNode++; +} + +/* +** Return true if z[] begins with 4 (or more) hexadecimal digits +*/ +static int p21Is4Hex(const char *z){ + int i; + for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; + return 1; +} + +/* +** Parse P21 value which begins at pParse->zP21[i]. Return the +** index of the first character past the end of the value parsed. +** +** Return negative for a syntax error. +*/ +static int p21ParseValue(P21Parse *pParse, u32 i) { + static int cxtStack[P21_MAX_DEPTH]; + const unsigned char *sp, *cur, *mrk, *tok, *end; + /*!stags:re2c format = 'const unsigned char *@@;'; */ + int *piThis, x; + u32 n; + P21Node *pNode; + + sp = cur = tok = &pParse->zP21[i]; + piThis = cxtStack + pParse->iDepth; + +/*!re2c + re2c:yyfill:enable = 0; + re2c:flags:tags = 1; + re2c:define:YYCTYPE = 'unsigned char'; + re2c:define:YYCURSOR = 'cur'; + re2c:define:YYMARKER = 'mrk'; + + ascii_encoding = [][!"*$%&.#+,\-()?/:;<=>@{}|^`~0-9a-zA-Z_ ] | "''" | "\\" ; + page_encoding = "\\" [A-I] "\\" | "\\S\\" [][!"'*$%&.#+,\-()?/:;<=>@{}|^`~0-9a-zA-Z_\\ ] ; + hex_encoding = "\\X2\\" ([0-9A-F]{4})+ "\\X0\\" | "\\X4\\" ([0-9A-F]{8})+ "\\X0\\" ; + byte_encoding = "\\X\\" [0-9A-F]{2} ; + + WS = [ \t\r\n] ; + KEYWORD = "!"? [A-Za-z_] [0-9A-Za-z_]* ; + REAL = [+-]* [0-9] [0-9]* "." [0-9]* ("E" [+-]* [0-9] [0-9]*)? ; + INTEGER = [+-]* [0-9] [0-9]* ; + STRING = "'" (ascii_encoding | page_encoding | hex_encoding | byte_encoding )* "'" ; + BINARY = '"' [0-3] [0-9A-F]* '"' ; + ENUMERATION = "." [A-Z_] [A-Z0-9_]* "." ; + EID = "#" [0-9]+ ; + */ + +start: + + tok = cur; +/*!re2c + WS+ { + goto start; + } + "(" { + /* (complex_entity_instance) parameter_list */ + *piThis = p21ParseAddNode(pParse, P21_LIST, 0, 0); + if (*piThis < 0) return -1; + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto keywords; + } + "" { + /* (simple_entity_instance) parameter_list */ + *piThis = p21ParseAddNode(pParse, P21_RECORD, 0, 0); + if (*piThis < 0) return -1; + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params1; + } + */ + +keywords: + tok = cur; + +/*!re2c + WS+ { + goto keywords; + } + KEYWORD @end WS* "(" { + *piThis = p21ParseAddNode(pParse, P21_RECORD, 0, tok); + if (*piThis < 0) return -1; + pParse->aNode[*piThis].n_kw = (u16)(end - tok); + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params2; + } + ")" { + piThis = cxtStack + --pParse->iDepth; + pNode = pParse->aNode + *piThis; + assert(pNode->eType == P21_LIST); + + pNode->n = pParse->nNode - (u32)*piThis - 1; + goto eol; + } + "" { + /* fix-up and revert to P21_RECORD */ + pNode = pParse->aNode + *(piThis - 1); + pNode->eType = P21_RECORD; + assert(pParse->iDepth == 1); + goto params1; + } + */ + +params1: + tok = cur; + +/*!re2c + WS+ { + goto params1; + } + KEYWORD @end WS* "(" { + *piThis = p21ParseAddNode(pParse, P21_RECORD, 0, tok); + if (*piThis < 0) return -1; + pParse->aNode[*piThis].n_kw = (u16)(end - tok); + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params1; + } + "(" { + *piThis = p21ParseAddNode(pParse, P21_LIST, 0, 0); + if (*piThis < 0) return -1; + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params1; + } + "," { + goto params1; + } + REAL { + p21ParseAddNode(pParse, P21_REAL, cur - tok, tok); + goto params1; + } + INTEGER { + p21ParseAddNode(pParse, P21_INTEGER, cur - tok, tok); + goto params1; + } + STRING { + p21ParseAddNode(pParse, P21_STRING, cur - tok, tok); + goto params1; + } + BINARY { + p21ParseAddNode(pParse, P21_BINARY, cur - tok, tok); + goto params1; + } + ENUMERATION { + p21ParseAddNode(pParse, P21_ENUMERATION, cur - tok, tok); + goto params1; + } + EID { + p21ParseAddNode(pParse, P21_EID, cur - tok, tok); + goto params1; + } + "$" { + p21ParseAddNode(pParse, P21_EMPTY, cur - tok, tok); + goto params1; + } + "*" { + p21ParseAddNode(pParse, P21_DERIVED, cur - tok, tok); + goto params1; + } + ")" { + piThis = cxtStack + --pParse->iDepth; + pNode = pParse->aNode + *piThis; + pNode->n = pParse->nNode - (u32)*piThis - 1; + goto params1; + } + "" { + if (pParse->iDepth) --pParse->iDepth; + piThis = cxtStack + pParse->iDepth; + pNode = pParse->aNode + *piThis; + assert(pNode->eType == P21_RECORD); + pNode->n = pParse->nNode - (u32)*piThis - 1; + goto eol; + } + */ + +params2: + tok = cur; + +/*!re2c + WS+ { + goto params2; + } + KEYWORD @end WS* "(" { + *piThis = p21ParseAddNode(pParse, P21_RECORD, 0, tok); + if (*piThis < 0) return -1; + pParse->aNode[*piThis].n_kw = (u16)(end - tok); + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params2; + } + "(" { + *piThis = p21ParseAddNode(pParse, P21_LIST, 0, 0); + if (*piThis < 0) return -1; + + if( ++pParse->iDepth > P21_MAX_DEPTH ) return -1; + piThis = cxtStack + pParse->iDepth; + goto params2; + } + "," { + goto params2; + } + REAL { + p21ParseAddNode(pParse, P21_REAL, cur - tok, tok); + goto params2; + } + INTEGER { + p21ParseAddNode(pParse, P21_INTEGER, cur - tok, tok); + goto params2; + } + STRING { + p21ParseAddNode(pParse, P21_STRING, cur - tok, tok); + goto params2; + } + BINARY { + p21ParseAddNode(pParse, P21_BINARY, cur - tok, tok); + goto params2; + } + ENUMERATION { + p21ParseAddNode(pParse, P21_ENUMERATION, cur - tok, tok); + goto params2; + } + EID { + p21ParseAddNode(pParse, P21_EID, cur - tok, tok); + goto params2; + } + "$" { + p21ParseAddNode(pParse, P21_EMPTY, cur - tok, tok); + goto params2; + } + "*" { + p21ParseAddNode(pParse, P21_DERIVED, cur - tok, tok); + goto params2; + } + ")" { + piThis = cxtStack + --pParse->iDepth; + pNode = pParse->aNode + *piThis; + pNode->n = pParse->nNode - (u32)*piThis - 1; + if (pParse->iDepth > 1) { + goto params2; + } else { + goto keywords; + } + } + /* continue to next block for error handling */ + */ + +eol: + tok = cur; + +/*!re2c + [\x00] { + return cur - sp; + } + * { + return -1; + } + */ + +} + + +/* +** Parse a complete P21 string. Return 0 on success or non-zero if there +** are any errors. If an error occurs, free all memory associated with +** pParse. +** +** pParse is uninitialized when this routine is called. +*/ +static int p21Parse( + P21Parse *pParse, /* Initialize and fill this P21Parse object */ + sqlite3_context *pCtx, /* Report errors here */ + const char *zP21 /* Input P21 text to be parsed */ +){ + int i; + memset(pParse, 0, sizeof(*pParse)); + if( zP21==0 ) return 1; + pParse->zP21 = zP21; + i = p21ParseValue(pParse, 0); + if( pParse->oom ) i = -1; + if( i>0 ){ + assert( pParse->iDepth==0 ); + } + if( i<=0 ){ + if( pCtx!=0 ){ + if( pParse->oom ){ + sqlite3_result_error_nomem(pCtx); + }else{ + sqlite3_result_error(pCtx, "malformed P21", -1); + } + } + p21ParseReset(pParse); + return 1; + } + return 0; +} + +/* Mark node i of pParse as being a child of iParent. Call recursively +** to fill in all the descendants of node i. +*/ +static void p21ParseFillInParentage(P21Parse *pParse, u32 i, u32 iParent){ + P21Node *pNode = &pParse->aNode[i]; + u32 j; + pParse->aUp[i] = iParent; + switch( pNode->eType ){ + case P21_RECORD: + case P21_LIST: { + for(j=1; j<=pNode->n; j += p21NodeSize(pNode+j)){ + p21ParseFillInParentage(pParse, i+j, i); + } + break; + } + default: { + break; + } + } +} + +/* +** Compute the parentage of all nodes in a completed parse. +*/ +static int p21ParseFindParents(P21Parse *pParse){ + u32 *aUp; + assert( pParse->aUp==0 ); + aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode ); + if( aUp==0 ){ + pParse->oom = 1; + return SQLITE_NOMEM; + } + p21ParseFillInParentage(pParse, 0, 0); + return SQLITE_OK; +} + +/* +** Magic number used for the P21 parse cache in sqlite3_get_auxdata() +*/ +#define P21_CACHE_ID (-429938) /* First cache entry */ +#define P21_CACHE_SZ 4 /* Max number of cache entries */ + +/* +** Obtain a complete parse of the P21 found in the first argument +** of the argv array. Use the sqlite3_get_auxdata() cache for this +** parse if it is available. If the cache is not available or if it +** is no longer valid, parse the P21 again and return the new parse, +** and also register the new parse so that it will be available for +** future sqlite3_get_auxdata() calls. +*/ +static P21Parse *p21ParseCached( + sqlite3_context *pCtx, + sqlite3_value **argv, + sqlite3_context *pErrCtx +){ + const char *zP21 = (const char*)sqlite3_value_text(argv[0]); + int nP21 = sqlite3_value_bytes(argv[0]); + P21Parse *p; + P21Parse *pMatch = 0; + int iKey; + int iMinKey = 0; + u32 iMinHold = 0xffffffff; + u32 iMaxHold = 0; + if( zP21==0 ) return 0; + for(iKey=0; iKeynP21==nP21 + && memcmp(p->zP21,zP21,nP21)==0 + ){ + p->nErr = 0; + pMatch = p; + }else if( p->iHoldiHold; + iMinKey = iKey; + } + if( p->iHold>iMaxHold ){ + iMaxHold = p->iHold; + } + } + if( pMatch ){ + pMatch->nErr = 0; + pMatch->iHold = iMaxHold+1; + return pMatch; + } + p = sqlite3_malloc64( sizeof(*p) + nP21 + 1 ); + if( p==0 ){ + sqlite3_result_error_nomem(pCtx); + return 0; + } + memset(p, 0, sizeof(*p)); + p->zP21 = (char*)&p[1]; + memcpy((char*)p->zP21, zP21, nP21+1); + if( p21Parse(p, pErrCtx, p->zP21) ){ + sqlite3_free(p); + return 0; + } + p->nP21 = nP21; + p->iHold = iMaxHold+1; + sqlite3_set_auxdata(pCtx, P21_CACHE_ID+iMinKey, p, + (void(*)(void*))p21ParseFree); + return (P21Parse*)sqlite3_get_auxdata(pCtx, P21_CACHE_ID+iMinKey); +} + +/* +** Compare the OBJECT label at pNode against zKey,nKey. Return true on +** a match. +*/ +static int p21LabelCompare(P21Node *pNode, const char *zKey, u32 nKey){ + if( pNode->jnFlags & PNODE_RAW ){ + if( pNode->n!=nKey ) return 0; + return strncmp(pNode->u.zJContent, zKey, nKey)==0; + }else{ + if( pNode->n!=nKey+2 ) return 0; + return strncmp(pNode->u.zJContent+1, zKey, nKey)==0; + } +} + +/* forward declaration */ +static P21Node *p21LookupAppend(P21Parse*,const char*,int*,const char**); + +/* +** Search along zPath to find the node specified. Return a pointer +** to that node, or NULL if zPath is malformed or if there is no such +** node. +** +** If pApnd!=0, then try to append new nodes to complete zPath if it is +** possible to do so and if no existing node corresponds to zPath. If +** new nodes are appended *pApnd is set to 1. +*/ +static P21Node *p21LookupStep( + P21Parse *pParse, /* The P21 to search */ + u32 iRoot, /* Begin the search at this node */ + const char *zPath, /* The path to search */ + int *pApnd, /* Append nodes to complete path if not NULL */ + const char **pzErr /* Make *pzErr point to any syntax error in zPath */ +){ + u32 i, j, nKey; + const char *zKey; + P21Node *pRoot = &pParse->aNode[iRoot]; + if( zPath[0]==0 ) return pRoot; + if( pRoot->jnFlags & PNODE_REPLACE ) return 0; + if( zPath[0]=='.' ){ + if( pRoot->eType!=P21_RECORD ) return 0; + zPath++; + if( zPath[0]=='"' ){ + zKey = zPath + 1; + for(i=1; zPath[i] && zPath[i]!='"'; i++){} + nKey = i-1; + if( zPath[i] ){ + i++; + }else{ + *pzErr = zPath; + return 0; + } + }else{ + zKey = zPath; + for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} + nKey = i; + } + if( nKey==0 ){ + *pzErr = zPath; + return 0; + } + j = 1; + for(;;){ + while( j<=pRoot->n ){ + if( p21LabelCompare(pRoot+j, zKey, nKey) ){ + return p21LookupStep(pParse, iRoot+j+1, &zPath[i], pApnd, pzErr); + } + j++; + j += p21NodeSize(&pRoot[j]); + } + if( (pRoot->jnFlags & PNODE_APPEND)==0 ) break; + iRoot += pRoot->u.iAppend; + pRoot = &pParse->aNode[iRoot]; + j = 1; + } + if( pApnd ){ + u32 iStart, iLabel; + P21Node *pNode; + iStart = p21ParseAddNode(pParse, P21_RECORD, 2, 0); + iLabel = p21ParseAddNode(pParse, P21_STRING, nKey, zKey); + zPath += i; + pNode = p21LookupAppend(pParse, zPath, pApnd, pzErr); + if( pParse->oom ) return 0; + if( pNode ){ + pRoot = &pParse->aNode[iRoot]; + pRoot->u.iAppend = iStart - iRoot; + pRoot->jnFlags |= PNODE_APPEND; + pParse->aNode[iLabel].jnFlags |= PNODE_RAW; + } + return pNode; + } + }else if( zPath[0]=='[' ){ + i = 0; + j = 1; + while( safe_isdigit(zPath[j]) ){ + i = i*10 + zPath[j] - '0'; + j++; + } + if( j<2 || zPath[j]!=']' ){ + if( zPath[1]=='#' ){ + P21Node *pBase = pRoot; + int iBase = iRoot; + if( pRoot->eType!=P21_LIST && pRoot->eType!=P21_RECORD) return 0; + for(;;){ + while( j<=pBase->n ){ + if( (pBase[j].jnFlags & PNODE_REMOVE)==0 ) i++; + j += p21NodeSize(&pBase[j]); + } + if( (pBase->jnFlags & PNODE_APPEND)==0 ) break; + iBase += pBase->u.iAppend; + pBase = &pParse->aNode[iBase]; + j = 1; + } + j = 2; + if( zPath[2]=='-' && safe_isdigit(zPath[3]) ){ + unsigned int x = 0; + j = 3; + do{ + x = x*10 + zPath[j] - '0'; + j++; + }while( safe_isdigit(zPath[j]) ); + if( x>i ) return 0; + i -= x; + } + if( zPath[j]!=']' ){ + *pzErr = zPath; + return 0; + } + }else{ + *pzErr = zPath; + return 0; + } + } + if( pRoot->eType!=P21_LIST && pRoot->eType!=P21_RECORD ) return 0; + zPath += j + 1; + j = 1; + for(;;){ + while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & PNODE_REMOVE)!=0) ){ + if( (pRoot[j].jnFlags & PNODE_REMOVE)==0 ) i--; + j += p21NodeSize(&pRoot[j]); + } + if( (pRoot->jnFlags & PNODE_APPEND)==0 ) break; + iRoot += pRoot->u.iAppend; + pRoot = &pParse->aNode[iRoot]; + j = 1; + } + if( j<=pRoot->n ){ + return p21LookupStep(pParse, iRoot+j, zPath, pApnd, pzErr); + } + if( i==0 && pApnd ){ + u32 iStart; + P21Node *pNode; + iStart = p21ParseAddNode(pParse, P21_LIST, 1, 0); + pNode = p21LookupAppend(pParse, zPath, pApnd, pzErr); + if( pParse->oom ) return 0; + if( pNode ){ + pRoot = &pParse->aNode[iRoot]; + pRoot->u.iAppend = iStart - iRoot; + pRoot->jnFlags |= PNODE_APPEND; + } + return pNode; + } + }else{ + *pzErr = zPath; + } + return 0; +} + +/* +** Append content to pParse that will complete zPath. Return a pointer +** to the inserted node, or return NULL if the append fails. +*/ +static P21Node *p21LookupAppend( + P21Parse *pParse, /* Append content to the P21 parse */ + const char *zPath, /* Description of content to append */ + int *pApnd, /* Set this flag to 1 */ + const char **pzErr /* Make this point to any syntax error */ +){ + *pApnd = 1; + if( zPath[0]==0 ){ + p21ParseAddNode(pParse, P21_EMPTY, 0, 0); + return pParse->oom ? 0 : &pParse->aNode[pParse->nNode-1]; + } + if( zPath[0]=='.' ){ + p21ParseAddNode(pParse, P21_RECORD, 0, 0); + }else if( strncmp(zPath,"[0]",3)==0 ){ + p21ParseAddNode(pParse, P21_LIST, 0, 0); + }else{ + return 0; + } + if( pParse->oom ) return 0; + return p21LookupStep(pParse, pParse->nNode-1, zPath, pApnd, pzErr); +} + +/* +** Return the text of a syntax error message on a P21 path. Space is +** obtained from sqlite3_malloc(). +*/ +static char *p21PathSyntaxError(const char *zErr){ + return sqlite3_mprintf("P21 path error near '%q'", zErr); +} + +/* +** Do a node lookup using zPath. Return a pointer to the node on success. +** Return NULL if not found or if there is an error. +** +** On an error, write an error message into pCtx and increment the +** pParse->nErr counter. +** +** If pApnd!=NULL then try to append missing nodes and set *pApnd = 1 if +** nodes are appended. +*/ +static P21Node *p21Lookup( + P21Parse *pParse, /* The P21 to search */ + const char *zPath, /* The path to search */ + int *pApnd, /* Append nodes to complete path if not NULL */ + sqlite3_context *pCtx /* Report errors here, if not NULL */ +){ + const char *zErr = 0; + P21Node *pNode = 0; + char *zMsg; + + if( zPath==0 ) return 0; + if( zPath[0]!='$' ){ + zErr = zPath; + goto lookup_err; + } + zPath++; + pNode = p21LookupStep(pParse, 0, zPath, pApnd, &zErr); + if( zErr==0 ) return pNode; + +lookup_err: + pParse->nErr++; + assert( zErr!=0 && pCtx!=0 ); + zMsg = p21PathSyntaxError(zErr); + if( zMsg ){ + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); + }else{ + sqlite3_result_error_nomem(pCtx); + } + return 0; +} + + +/* +** Report the wrong number of arguments for p21_insert(), p21_replace() +** or p21_set(). +*/ +static void p21WrongNumArgs( + sqlite3_context *pCtx, + const char *zFuncName +){ + char *zMsg = sqlite3_mprintf("p21_%s() needs an odd number of arguments", + zFuncName); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); +} + +/* +** Mark all NULL entries in the Object passed in as PNODE_REMOVE. +*/ +static void p21RemoveAllNulls(P21Node *pNode){ + int i, n; + assert( pNode->eType==P21_RECORD ); + n = pNode->n; + for(i=2; i<=n; i += p21NodeSize(&pNode[i])+1){ + switch( pNode[i].eType ){ + case P21_EMPTY: + pNode[i].jnFlags |= PNODE_REMOVE; + break; + case P21_RECORD: + p21RemoveAllNulls(&pNode[i]); + break; + } + } +} + + +/**************************************************************************** +** SQL functions used for testing and debugging +****************************************************************************/ + +#ifdef SQLITE_DEBUG +/* +** The p21_parse(P21) function returns a string which describes +** a parse of the P21 provided. Or it returns NULL if P21 is not +** well-formed. +*/ +static void p21ParseFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21String s; /* Output string - not real P21 */ + P21Parse x; /* The parse */ + u32 i; + + assert( argc==1 ); + if( p21Parse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + p21ParseFindParents(&x); + p21Init(&s, ctx); + for(i=0; inNode ); + if( argc==2 ){ + const char *zPath = (const char*)sqlite3_value_text(argv[1]); + pNode = p21Lookup(p, zPath, 0, ctx); + }else{ + pNode = p->aNode; + } + if( pNode==0 ){ + return; + } + if( pNode->eType==P21_LIST ){ + assert( (pNode->jnFlags & PNODE_APPEND)==0 ); + for(i=1; i<=pNode->n; n++){ + i += p21NodeSize(&pNode[i]); + } + } + sqlite3_result_int64(ctx, n); +} + +/* +** p21_extract(P21, PATH, ...) +** +** Return the element described by PATH. Return NULL if there is no +** PATH element. If there are multiple PATHs, then return a P21 array +** with the result from each path. Throw an error if the P21 or any PATH +** is malformed. +*/ +static void p21ExtractFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse *p; /* The parse */ + P21Node *pNode; + const char *zPath; + P21String jx; + int i; + + if( argc<2 ) return; + p = p21ParseCached(ctx, argv, ctx); + if( p==0 ) return; + p21Init(&jx, ctx); + p21AppendChar(&jx, '['); + for(i=1; inErr ) break; + if( argc>2 ){ + p21AppendSeparator(&jx); + if( pNode ){ + p21RenderNode(pNode, &jx, 0); + }else{ + p21AppendRaw(&jx, "null", 4); + } + }else if( pNode ){ + p21Return(pNode, ctx, 0); + } + } + if( argc>2 && i==argc ){ + p21AppendChar(&jx, ']'); + p21Result(&jx); + sqlite3_result_subtype(ctx, P21_SUBTYPE); + } + p21Reset(&jx); +} + +#if 0 +/* TODO: a MergeRecord function could be useful + */ +static P21Node *p21MergePatch( + P21Parse *pParse, /* The P21 parser that contains the TARGET */ + u32 iTarget, /* Node of the TARGET in pParse */ + P21Node *pPatch /* The PATCH */ +){ + u32 i, j; + u32 iRoot; + P21Node *pTarget; + if( pPatch->eType!=P21_RECORD ){ + return pPatch; + } + assert( iTargetnNode ); + pTarget = &pParse->aNode[iTarget]; + assert( (pPatch->jnFlags & PNODE_APPEND)==0 ); + if( pTarget->eType!=P21_RECORD ){ + p21RemoveAllNulls(pPatch); + return pPatch; + } + iRoot = iTarget; + for(i=1; in; i += p21NodeSize(&pPatch[i+1])+1){ + u32 nKey; + const char *zKey; + assert( pPatch[i].eType==P21_STRING ); + assert( pPatch[i].jnFlags & PNODE_LABEL ); + nKey = pPatch[i].n; + zKey = pPatch[i].u.zJContent; + assert( (pPatch[i].jnFlags & PNODE_RAW)==0 ); + for(j=1; jn; j += p21NodeSize(&pTarget[j+1])+1 ){ + assert( pTarget[j].eType==P21_STRING ); + assert( pTarget[j].jnFlags & PNODE_LABEL ); + assert( (pPatch[i].jnFlags & PNODE_RAW)==0 ); + if( pTarget[j].n==nKey && strncmp(pTarget[j].u.zJContent,zKey,nKey)==0 ){ + if( pTarget[j+1].jnFlags & (PNODE_REMOVE|PNODE_PATCH) ) break; + if( pPatch[i+1].eType==P21_EMPTY ){ + pTarget[j+1].jnFlags |= PNODE_REMOVE; + }else{ + P21Node *pNew = p21MergePatch(pParse, iTarget+j+1, &pPatch[i+1]); + if( pNew==0 ) return 0; + pTarget = &pParse->aNode[iTarget]; + if( pNew!=&pTarget[j+1] ){ + pTarget[j+1].u.pPatch = pNew; + pTarget[j+1].jnFlags |= PNODE_PATCH; + } + } + break; + } + } + if( j>=pTarget->n && pPatch[i+1].eType!=P21_EMPTY ){ + int iStart, iPatch; + iStart = p21ParseAddNode(pParse, P21_RECORD, 2, 0); + p21ParseAddNode(pParse, P21_STRING, nKey, zKey); + iPatch = p21ParseAddNode(pParse, P21_TRUE, 0, 0); + if( pParse->oom ) return 0; + p21RemoveAllNulls(pPatch); + pTarget = &pParse->aNode[iTarget]; + pParse->aNode[iRoot].jnFlags |= PNODE_APPEND; + pParse->aNode[iRoot].u.iAppend = iStart - iRoot; + iRoot = iStart; + pParse->aNode[iPatch].jnFlags |= PNODE_PATCH; + pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; + } + } + return pTarget; +} + + +/* +** Implementation of the json_mergepatch(JSON1,JSON2) function. Return a P21 +** object that is the result of running the RFC 7396 MergePatch() algorithm +** on the two arguments. +*/ +static void p21PatchFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse x; /* The P21 that is being patched */ + P21Parse y; /* The patch */ + P21Node *pResult; /* The result of the merge */ + + UNUSED_PARAM(argc); + if( p21Parse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + if( p21Parse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ + p21ParseReset(&x); + return; + } + pResult = p21MergePatch(&x, 0, y.aNode); + assert( pResult!=0 || x.oom ); + if( pResult ){ + p21ReturnP21(pResult, ctx, 0); + }else{ + sqlite3_result_error_nomem(ctx); + } + p21ParseReset(&x); + p21ParseReset(&y); +} +#endif + +/* +** Implementation of the p21_object(NAME,VALUE,...) function. Return a P21 +** object that contains all name/value given in arguments. Or if any name +** is not a string or if any value is a BLOB, throw an error. +*/ +static void p21ObjectFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + int i; + P21String jx; + const char *z; + u32 n; + + if( argc&1 ){ + sqlite3_result_error(ctx, "p21_object() requires an even number " + "of arguments", -1); + return; + } + p21Init(&jx, ctx); + p21AppendChar(&jx, '{'); + for(i=0; ijnFlags |= PNODE_REMOVE; + } + if( (x.aNode[0].jnFlags & PNODE_REMOVE)==0 ){ + p21ReturnP21(x.aNode, ctx, 0); + } +remove_done: + p21ParseReset(&x); +} + +/* +** p21_replace(P21, PATH, VALUE, ...) +** +** Replace the value at PATH with VALUE. If PATH does not already exist, +** this routine is a no-op. If P21 or PATH is malformed, throw an error. +*/ +static void p21ReplaceFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse x; /* The parse */ + P21Node *pNode; + const char *zPath; + u32 i; + + if( argc<1 ) return; + if( (argc&1)==0 ) { + p21WrongNumArgs(ctx, "replace"); + return; + } + if( p21Parse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + assert( x.nNode ); + for(i=1; i<(u32)argc; i+=2){ + zPath = (const char*)sqlite3_value_text(argv[i]); + pNode = p21Lookup(&x, zPath, 0, ctx); + if( x.nErr ) goto replace_err; + if( pNode ){ + pNode->jnFlags |= (u8)PNODE_REPLACE; + pNode->u.iReplace = i + 1; + } + } + if( x.aNode[0].jnFlags & PNODE_REPLACE ){ + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); + }else{ + p21ReturnP21(x.aNode, ctx, argv); + } +replace_err: + p21ParseReset(&x); +} + +/* +** p21_set(P21, PATH, VALUE, ...) +** +** Set the value at PATH to VALUE. Create the PATH if it does not already +** exist. Overwrite existing values that do exist. +** If P21 or PATH is malformed, throw an error. +** +** p21_insert(P21, PATH, VALUE, ...) +** +** Create PATH and initialize it to VALUE. If PATH already exists, this +** routine is a no-op. If P21 or PATH is malformed, throw an error. +*/ +static void p21SetFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse x; /* The parse */ + P21Node *pNode; + const char *zPath; + u32 i; + int bApnd; + int bIsSet = *(int*)sqlite3_user_data(ctx); + + if( argc<1 ) return; + if( (argc&1)==0 ) { + p21WrongNumArgs(ctx, bIsSet ? "set" : "insert"); + return; + } + if( p21Parse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + assert( x.nNode ); + for(i=1; i<(u32)argc; i+=2){ + zPath = (const char*)sqlite3_value_text(argv[i]); + bApnd = 0; + pNode = p21Lookup(&x, zPath, &bApnd, ctx); + if( x.oom ){ + sqlite3_result_error_nomem(ctx); + goto p21SetDone; + }else if( x.nErr ){ + goto p21SetDone; + }else if( pNode && (bApnd || bIsSet) ){ + pNode->jnFlags |= (u8)PNODE_REPLACE; + pNode->u.iReplace = i + 1; + } + } + if( x.aNode[0].jnFlags & PNODE_REPLACE ){ + sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); + }else{ + p21ReturnP21(x.aNode, ctx, argv); + } +p21SetDone: + p21ParseReset(&x); +} + +/* +** p21_type(P21) +** p21_type(P21, PATH) +** +** Return the top-level "type" of a P21 string. Throw an error if +** either the P21 or PATH inputs are not well-formed. +*/ +static void p21TypeFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse *p; /* The parse */ + const char *zPath; + P21Node *pNode; + + p = p21ParseCached(ctx, argv, ctx); + if( p==0 ) return; + if( argc==2 ){ + zPath = (const char*)sqlite3_value_text(argv[1]); + pNode = p21Lookup(p, zPath, 0, ctx); + }else{ + pNode = p->aNode; + } + if( pNode ){ + sqlite3_result_text(ctx, p21Type[pNode->eType], -1, SQLITE_STATIC); + } +} + +/* +** p21_valid(P21) +** +** Return 1 if P21 is a well-formed P21 string according to RFC-7159. +** Return 0 otherwise. +*/ +static void p21ValidFunc( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21Parse *p; /* The parse */ + UNUSED_PARAM(argc); + p = p21ParseCached(ctx, argv, 0); + sqlite3_result_int(ctx, p!=0); +} + + +/**************************************************************************** +** Aggregate SQL function implementations +****************************************************************************/ +/* +** p21_group_array(VALUE) +** +** Return a P21 array composed of all values in the aggregate. +*/ +static void p21ArrayStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21String *pStr; + UNUSED_PARAM(argc); + pStr = (P21String*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + if( pStr->zBuf==0 ){ + p21Init(pStr, ctx); + p21AppendChar(pStr, '['); + }else if( pStr->nUsed>1 ){ + p21AppendChar(pStr, ','); + pStr->pCtx = ctx; + } + p21AppendValue(pStr, argv[0]); + } +} +static void p21ArrayCompute(sqlite3_context *ctx, int isFinal){ + P21String *pStr; + pStr = (P21String*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + pStr->pCtx = ctx; + p21AppendChar(pStr, ']'); + if( pStr->bErr ){ + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); + assert( pStr->bStatic ); + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + pStr->nUsed--; + } + }else{ + sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, P21_SUBTYPE); +} +static void p21ArrayValue(sqlite3_context *ctx){ + p21ArrayCompute(ctx, 0); +} +static void p21ArrayFinal(sqlite3_context *ctx){ + p21ArrayCompute(ctx, 1); +} + +#ifndef SQLITE_OMIT_WINDOWFUNC +/* +** This method works for both p21_group_array() and p21_group_object(). +** It works by removing the first element of the group by searching forward +** to the first comma (",") that is not within a string and deleting all +** text through that comma. +*/ +static void p21GroupInverse( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + unsigned int i; + int inStr = 0; + int nNest = 0; + char *z; + char c; + P21String *pStr; + UNUSED_PARAM(argc); + UNUSED_PARAM(argv); + pStr = (P21String*)sqlite3_aggregate_context(ctx, 0); +#ifdef NEVER + /* pStr is always non-NULL since p21ArrayStep() or p21ObjectStep() will + ** always have been called to initalize it */ + if( NEVER(!pStr) ) return; +#endif + z = pStr->zBuf; + for(i=1; (c = z[i])!=',' || inStr || nNest; i++){ + if( i>=pStr->nUsed ){ + pStr->nUsed = 1; + return; + } + if( c=='"' ){ + inStr = !inStr; + }else if( c=='\\' ){ + i++; + }else if( !inStr ){ + if( c=='{' || c=='[' ) nNest++; + if( c=='}' || c==']' ) nNest--; + } + } + pStr->nUsed -= i; + memmove(&z[1], &z[i+1], (size_t)pStr->nUsed-1); +} +#else +# define p21GroupInverse 0 +#endif + + +/* +** p21_group_obj(NAME,VALUE) +** +** Return a P21 object composed of all names and values in the aggregate. +*/ +static void p21ObjectStep( + sqlite3_context *ctx, + int argc, + sqlite3_value **argv +){ + P21String *pStr; + const char *z; + u32 n; + UNUSED_PARAM(argc); + pStr = (P21String*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); + if( pStr ){ + if( pStr->zBuf==0 ){ + p21Init(pStr, ctx); + p21AppendChar(pStr, '{'); + }else if( pStr->nUsed>1 ){ + p21AppendChar(pStr, ','); + pStr->pCtx = ctx; + } + z = (const char*)sqlite3_value_text(argv[0]); + n = (u32)sqlite3_value_bytes(argv[0]); + p21AppendString(pStr, z, n); + p21AppendChar(pStr, ':'); + p21AppendValue(pStr, argv[1]); + } +} +static void p21ObjectCompute(sqlite3_context *ctx, int isFinal){ + P21String *pStr; + pStr = (P21String*)sqlite3_aggregate_context(ctx, 0); + if( pStr ){ + p21AppendChar(pStr, '}'); + if( pStr->bErr ){ + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); + assert( pStr->bStatic ); + }else if( isFinal ){ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic = 1; + }else{ + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + pStr->nUsed--; + } + }else{ + sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); + } + sqlite3_result_subtype(ctx, P21_SUBTYPE); +} +static void p21ObjectValue(sqlite3_context *ctx){ + p21ObjectCompute(ctx, 0); +} +static void p21ObjectFinal(sqlite3_context *ctx){ + p21ObjectCompute(ctx, 1); +} + + + +#ifndef SQLITE_OMIT_VIRTUALTABLE +/**************************************************************************** +** The p21_each virtual table +****************************************************************************/ +typedef struct P21EachCursor P21EachCursor; +struct P21EachCursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + u32 iRowid; /* The rowid */ + u32 iBegin; /* The first node of the scan */ + u32 i; /* Index in sParse.aNode[] of current row */ + u32 iEnd; /* EOF when i equals or exceeds this value */ + u8 eType; /* Type of top-level element */ + char *zP21; /* Input P21 */ + char *zRoot; /* Path by which to filter zP21 */ + P21Parse sParse; /* Parse of the input P21 */ +}; + +/* Constructor for the p21_each virtual table */ +static int p21EachConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + sqlite3_vtab *pNew; + int rc; + +/* Column numbers */ +#define PEACH_KEY 0 +#define PEACH_VALUE 1 +#define PEACH_TYPE 2 +#define PEACH_ATOM 3 +#define PEACH_ID 4 +#define PEACH_PARENT 5 +#define PEACH_FULLKEY 6 +#define PEACH_PATH 7 +/* The xBestIndex method assumes that the P21 and ROOT columns are +** the last two columns in the table. Should this ever changes, be +** sure to update the xBestIndex method. */ +#define PEACH_P21 8 +#define PEACH_ROOT 9 + + UNUSED_PARAM(pzErr); + UNUSED_PARAM(argv); + UNUSED_PARAM(argc); + UNUSED_PARAM(pAux); + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," + "p21 HIDDEN,root HIDDEN)"); + if( rc==SQLITE_OK ){ + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + } + return rc; +} + +/* destructor for p21_each virtual table */ +static int p21EachDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); + return SQLITE_OK; +} + +/* constructor for a P21EachCursor object for p21_each(). */ +static int p21EachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + P21EachCursor *pCur; + + UNUSED_PARAM(p); + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* Reset a P21EachCursor back to its original state. Free any memory +** held. */ +static void p21EachCursorReset(P21EachCursor *p){ + sqlite3_free(p->zP21); + sqlite3_free(p->zRoot); + p21ParseReset(&p->sParse); + p->iRowid = 0; + p->i = 0; + p->iEnd = 0; + p->eType = 0; + p->zP21 = 0; + p->zRoot = 0; +} + +/* Destructor for a p21EachCursor object */ +static int p21EachClose(sqlite3_vtab_cursor *cur){ + P21EachCursor *p = (P21EachCursor*)cur; + p21EachCursorReset(p); + sqlite3_free(cur); + return SQLITE_OK; +} + +/* Return TRUE if the p21EachCursor object has been advanced off the end +** of the P21 object */ +static int p21EachEof(sqlite3_vtab_cursor *cur){ + P21EachCursor *p = (P21EachCursor*)cur; + return p->i >= p->iEnd; +} + +/* Advance the cursor to the next element for p21_tree() */ +static int p21EachNext(sqlite3_vtab_cursor *cur){ + P21EachCursor *p = (P21EachCursor*)cur; + switch( p->eType ){ + case P21_RECORD: + case P21_LIST: { + p->i += p21NodeSize(&p->sParse.aNode[p->i]); + p->iRowid++; + break; + } + default: { + p->i = p->iEnd; + break; + } + } + return SQLITE_OK; +} + +/* Append the name of the path for element i to pStr +*/ +static void p21EachComputePath( + P21EachCursor *p, /* The cursor */ + P21String *pStr, /* Write the path here */ + u32 i /* Path to this element */ +){ + P21Node *pNode, *pUp; + u32 iUp; + if( i==0 ){ + p21AppendChar(pStr, '$'); + return; + } + iUp = p->sParse.aUp[i]; + p21EachComputePath(p, pStr, iUp); + pNode = &p->sParse.aNode[i]; + pUp = &p->sParse.aNode[iUp]; + if( pUp->eType==P21_LIST ){ + p21Printf(30, pStr, "[%d]", pUp->u.iKey); + }else{ + assert( pUp->eType==P21_RECORD ); + if( (pNode->jnFlags & PNODE_LABEL)==0 ) pNode--; + assert( pNode->eType==P21_STRING ); + assert( pNode->jnFlags & PNODE_LABEL ); + p21Printf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); + } +} + +/* Return the value of a column */ +static int p21EachColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + P21EachCursor *p = (P21EachCursor*)cur; + P21Node *pThis = &p->sParse.aNode[p->i]; + switch( i ){ + case PEACH_KEY: { + if( p->i==0 ) break; + if( p->eType==P21_RECORD ){ + p21Return(pThis, ctx, 0); + }else if( p->eType==P21_LIST ){ + u32 iKey; + iKey = p->iRowid; + sqlite3_result_int64(ctx, (sqlite3_int64)iKey); + } + break; + } + case PEACH_VALUE: { + if( pThis->jnFlags & PNODE_LABEL ) pThis++; + p21Return(pThis, ctx, 0); + break; + } + case PEACH_TYPE: { + if( pThis->jnFlags & PNODE_LABEL ) pThis++; + sqlite3_result_text(ctx, p21Type[pThis->eType], -1, SQLITE_STATIC); + break; + } + case PEACH_ATOM: { + if( pThis->jnFlags & PNODE_LABEL ) pThis++; + if( pThis->eType>=P21_LIST ) break; + p21Return(pThis, ctx, 0); + break; + } + case PEACH_ID: { + sqlite3_result_int64(ctx, + (sqlite3_int64)p->i + ((pThis->jnFlags & PNODE_LABEL)!=0)); + break; + } + case PEACH_FULLKEY: { + P21String x; + p21Init(&x, ctx); + if( p->zRoot ){ + p21AppendRaw(&x, p->zRoot, (int)strlen(p->zRoot)); + }else{ + p21AppendChar(&x, '$'); + } + if( p->eType==P21_LIST ){ + p21Printf(30, &x, "[%d]", p->iRowid); + }else if( p->eType==P21_RECORD ){ + p21Printf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); + } + p21Result(&x); + break; + } + case PEACH_PATH: + default: { + const char *zRoot = p->zRoot; + if( zRoot==0 ) zRoot = "$"; + sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); + break; + } + case PEACH_P21: { + assert( i==PEACH_P21 ); + sqlite3_result_text(ctx, p->sParse.zP21, -1, SQLITE_STATIC); + break; + } + } + return SQLITE_OK; +} + +/* Return the current rowid value */ +static int p21EachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + P21EachCursor *p = (P21EachCursor*)cur; + *pRowid = p->iRowid; + return SQLITE_OK; +} + +/* The query strategy is to look for an equality constraint on the p21 +** column. Without such a constraint, the table cannot operate. idxNum is +** 1 if the constraint is found, 3 if the constraint and zRoot are found, +** and 0 otherwise. +*/ +static int p21EachBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + int i; /* Loop counter or computed array index */ + int aIdx[2]; /* Index of constraints for P21 and ROOT */ + int unusableMask = 0; /* Mask of unusable P21 and ROOT constraints */ + int idxMask = 0; /* Mask of usable == constraints P21 and ROOT */ + const struct sqlite3_index_constraint *pConstraint; + + /* This implementation assumes that P21 and ROOT are the last two + ** columns in the table */ + assert( PEACH_ROOT == PEACH_P21+1 ); + UNUSED_PARAM(tab); + aIdx[0] = aIdx[1] = -1; + pConstraint = pIdxInfo->aConstraint; + for(i=0; inConstraint; i++, pConstraint++){ + int iCol; + int iMask; + if( pConstraint->iColumn < PEACH_P21 ) continue; + iCol = pConstraint->iColumn - PEACH_P21; + assert( iCol==0 || iCol==1 ); + iMask = 1 << iCol; + if( pConstraint->usable==0 ){ + unusableMask |= iMask; + }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){ + aIdx[iCol] = i; + idxMask |= iMask; + } + } + if( (unusableMask & ~idxMask)!=0 ){ + /* If there are any unusable constraints on P21 or ROOT, then reject + ** this entire plan */ + return SQLITE_CONSTRAINT; + } + if( aIdx[0]<0 ){ + /* No P21 input. Leave estimatedCost at the huge value that it was + ** initialized to to discourage the query planner from selecting this + ** plan. */ + pIdxInfo->idxNum = 0; + }else{ + pIdxInfo->estimatedCost = 1.0; + i = aIdx[0]; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + pIdxInfo->aConstraintUsage[i].omit = 1; + if( aIdx[1]<0 ){ + pIdxInfo->idxNum = 1; /* Only P21 supplied. Plan 1 */ + }else{ + i = aIdx[1]; + pIdxInfo->aConstraintUsage[i].argvIndex = 2; + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->idxNum = 3; /* Both P21 and ROOT are supplied. Plan 3 */ + } + } + return SQLITE_OK; +} + +/* Start a search on a new P21 string */ +static int p21EachFilter( + sqlite3_vtab_cursor *cur, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + P21EachCursor *p = (P21EachCursor*)cur; + const char *z; + const char *zRoot = 0; + sqlite3_int64 n; + + UNUSED_PARAM(idxStr); + UNUSED_PARAM(argc); + p21EachCursorReset(p); + if( idxNum==0 ) return SQLITE_OK; + z = (const char*)sqlite3_value_text(argv[0]); + if( z==0 ) return SQLITE_OK; + n = sqlite3_value_bytes(argv[0]); + p->zP21 = sqlite3_malloc64( n+1 ); + if( p->zP21==0 ) return SQLITE_NOMEM; + memcpy(p->zP21, z, (size_t)n+1); + if( p21Parse(&p->sParse, 0, p->zP21) ){ + int rc = SQLITE_NOMEM; + if( p->sParse.oom==0 ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed P21"); + if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; + } + p21EachCursorReset(p); + return rc; + }else{ + P21Node *pNode = 0; + if( idxNum==3 ){ + const char *zErr = 0; + zRoot = (const char*)sqlite3_value_text(argv[1]); + if( zRoot==0 ) return SQLITE_OK; + n = sqlite3_value_bytes(argv[1]); + p->zRoot = sqlite3_malloc64( n+1 ); + if( p->zRoot==0 ) return SQLITE_NOMEM; + memcpy(p->zRoot, zRoot, (size_t)n+1); + if( zRoot[0]!='$' ){ + zErr = zRoot; + }else{ + pNode = p21LookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); + } + if( zErr ){ + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = p21PathSyntaxError(zErr); + p21EachCursorReset(p); + return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; + }else if( pNode==0 ){ + return SQLITE_OK; + } + }else{ + pNode = p->sParse.aNode; + } + p->iBegin = p->i = (int)(pNode - p->sParse.aNode); + p->eType = pNode->eType; + if( p->eType>=P21_LIST ){ + pNode->u.iKey = 0; + p->iEnd = p->i + pNode->n + 1; + p->i++; + }else{ + p->iEnd = p->i+1; + } + } + return SQLITE_OK; +} + +/* The methods of the p21_each virtual table */ +static sqlite3_module p21EachModule = { + 0, /* iVersion */ + 0, /* xCreate */ + p21EachConnect, /* xConnect */ + p21EachBestIndex, /* xBestIndex */ + p21EachDisconnect, /* xDisconnect */ + 0, /* xDestroy */ + p21EachOpenEach, /* xOpen - open a cursor */ + p21EachClose, /* xClose - close a cursor */ + p21EachFilter, /* xFilter - configure scan constraints */ + p21EachNext, /* xNext - advance a cursor */ + p21EachEof, /* xEof - check for end of scan */ + p21EachColumn, /* xColumn - read data */ + p21EachRowid, /* xRowid - read data */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindMethod */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0 /* xShadowName */ +}; + +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +/**************************************************************************** +** The following routines are the only publically visible identifiers in this +** file. Call the following routines in order to register the various SQL +** functions and the virtual table implemented by this file. +****************************************************************************/ + +int sqlite3P21sqlInit(sqlite3 *db){ + int rc = SQLITE_OK; + unsigned int i; + static const struct { + const char *zName; + int nArg; + int flag; + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); + } aFunc[] = { + { "p21", 1, 0, p21RemoveFunc }, + { "p21_array", -1, 0, p21ArrayFunc }, + { "p21_array_length", 1, 0, p21ArrayLengthFunc }, + { "p21_array_length", 2, 0, p21ArrayLengthFunc }, + { "p21_extract", -1, 0, p21ExtractFunc }, + { "p21_insert", -1, 0, p21SetFunc }, + { "p21_object", -1, 0, p21ObjectFunc }, +#if 0 + { "p21_patch", 2, 0, p21PatchFunc }, +#endif + { "p21_quote", 1, 0, p21QuoteFunc }, + { "p21_remove", -1, 0, p21RemoveFunc }, + { "p21_replace", -1, 0, p21ReplaceFunc }, + { "p21_set", -1, 1, p21SetFunc }, + { "p21_type", 1, 0, p21TypeFunc }, + { "p21_type", 2, 0, p21TypeFunc }, + { "p21_valid", 1, 0, p21ValidFunc }, + +#if SQLITE_DEBUG + /* DEBUG and TESTING functions */ + { "p21_parse", 1, 0, p21ParseFunc }, + { "p21_test1", 1, 0, p21Test1Func }, +#endif + }; + static const struct { + const char *zName; + int nArg; + void (*xStep)(sqlite3_context*,int,sqlite3_value**); + void (*xFinal)(sqlite3_context*); + void (*xValue)(sqlite3_context*); + } aAgg[] = { + { "p21_group_array", 1, + p21ArrayStep, p21ArrayFinal, p21ArrayValue }, + { "p21_group_object", 2, + p21ObjectStep, p21ObjectFinal, p21ObjectValue }, + }; +#ifndef SQLITE_OMIT_VIRTUALTABLE + static const struct { + const char *zName; + sqlite3_module *pModule; + } aMod[] = { + { "p21_each", &p21EachModule }, + }; +#endif + static const int enc = + SQLITE_UTF8 | + SQLITE_DETERMINISTIC | + SQLITE_INNOCUOUS; + for(i=0; i nor the names of its contributors may +# be used to endorse or promote products derived from this software without +# specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import unittest +from stepcode.Part21 import Parser + +ShapesSample =""" +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('simple example file'),'1'); +FILE_NAME('testfile.step','1997-10-06T16:15:42',('long forgotten'),('nist'),'0','1','2'); +FILE_SCHEMA(('example_schema')); +ENDSEC; +DATA; +#0=SQUARE('Square9',.BROWN.,13,15.,51.); +#1=CIRCLE('Circle8',.ORANGE.,19,12.); +#2=TRIANGLE('Triangle7',.BLACK.,67,84.,60.,25.); +#3=LINE(#6,#7); +#4=SHAPE('Shape4',.WHITE.,83); +#5=RECTANGLE('Rectangle8',.BROWN.,66,78.,95.); +#6=CARTESIAN_POINT(11.,67.,54.); +#7=CARTESIAN_POINT(1.,2.,3.); +ENDSEC; +END-ISO-10303-21; +""" + +class TestSample(unittest.TestCase): + def setUp(self): + self.parser = Parser() + def tearDown(self): + self.parser = None + + +class TestShapesParse(TestSample): + """ + Tests whether we're able to parse the shapes sample at all + """ + def test_parse(self): + model = self.parser.parse(ShapesSample) + self.assertIsNotNone(model) + + +class TestShapesHeader(TestSample): + """ + Test basic structure and payload of Header section + """ + def test_header_name(self): + model = self.parser.parse(ShapesSample) + self.assertEqual(model.header.file_name.params[0][0], "testfile.step") + + def test_header_schema(self): + model = self.parser.parse(ShapesSample) + self.assertEqual(model.header.file_schema.params[0][0][0], "example_schema") + + +class TestShapesData(TestSample): + """ + Test basic structure and shape of data section + """ + def test_data_section_form(self): + model = self.parser.parse(ShapesSample) + self.assertEqual(len(model.sections), 1) + self.assertEqual(len(model.sections[0].entities), 8) + + +class TestEntity(TestSample): + """ + Test structure and contents of several entities within the DATA section + """ + def test_line(self): + model = self.parser.parse(ShapesSample) + line = model.sections[0].entities[3] + self.assertEqual(line.type_name, "LINE") + self.assertEqual(line.ref, "#3") + self.assertEqual(line.params[0], ["#6", "#7"]) + + def test_rectangle8(self): + model = self.parser.parse(ShapesSample) + rect8 = model.sections[0].entities[5] + self.assertEqual(rect8.type_name, "RECTANGLE") + self.assertEqual(rect8.ref, "#5") + self.assertEqual(rect8.params[0], ['Rectangle8', '.BROWN.', 66, 78.0, 95.0]) + diff --git a/src/exp2python/test/test_unitary_schemas.py b/src/exp2python/python/tests/test_unitary_schemas.py similarity index 97% rename from src/exp2python/test/test_unitary_schemas.py rename to src/exp2python/python/tests/test_unitary_schemas.py index 6d5f7f23f..077644253 100644 --- a/src/exp2python/test/test_unitary_schemas.py +++ b/src/exp2python/python/tests/test_unitary_schemas.py @@ -1,7 +1,7 @@ # Copyright (c) 2011, Thomas Paviot (tpaviot@gmail.com) # All rights reserved. -# This file is part StepClassLibrary (SCL). +# This file is part of the STEPCODE project. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -31,14 +31,16 @@ import unittest import sys -sys.path.append('../examples/unitary_schemas') - -from SCL.SCLBase import * -from SCL.SimpleDataTypes import * -from SCL.ConstructedDataTypes import * -from SCL.AggregationDataTypes import * -from SCL.TypeChecker import check_type -from SCL.Expr import * +import os + +here = os.path.dirname(os.path.abspath(__file__)) +sys.path.append(os.path.join(here, "..", "..", "examples", "unitary_schemas")) + +from stepcode.SCLBase import * +from stepcode.SimpleDataTypes import * +from stepcode.ConstructedDataTypes import * +from stepcode.AggregationDataTypes import * +from stepcode.TypeChecker import check_type class TestSelectDataType(unittest.TestCase): ''' diff --git a/src/exp2python/src/classes.h b/src/exp2python/src/classes.h index c8642f217..a76cb6afa 100644 --- a/src/exp2python/src/classes.h +++ b/src/exp2python/src/classes.h @@ -70,7 +70,7 @@ typedef struct file_holder { } File_holder, FILES; /** these fields are used so that ENTITY types are processed in order - * when appearing in differnt schemas + * when appearing in different schemas */ typedef struct EntityTag_ * EntityTag; struct EntityTag_ { diff --git a/src/exp2python/src/classes_misc_python.c b/src/exp2python/src/classes_misc_python.c index 5462eddaa..5a34c5fa7 100644 --- a/src/exp2python/src/classes_misc_python.c +++ b/src/exp2python/src/classes_misc_python.c @@ -22,7 +22,7 @@ extern int multiple_inheritance; /****************************************************************** ** The following functions will be used *** -*** through out the the program exp2python ***/ +*** throughout the program exp2python ***/ /****************************************************************** @@ -111,7 +111,7 @@ ToUpper( char c ) { const char * StrToLower( const char * word ) { - static char newword [MAX_LEN]; + static char newword [MAX_LEN+1]; int i = 0; if( !word ) { return 0; @@ -126,7 +126,7 @@ StrToLower( const char * word ) { } const char * StrToUpper( const char * word ) { - static char newword [MAX_LEN]; + static char newword [MAX_LEN+1]; int i = 0; char ToUpper( char c ); @@ -140,7 +140,7 @@ const char * StrToUpper( const char * word ) { } const char * StrToConstant( const char * word ) { - static char newword [MAX_LEN]; + static char newword [MAX_LEN+1]; int i = 0; while( word [i] != '\0' ) { @@ -194,7 +194,7 @@ int isAggregateType( const Type t ) { */ const char * ClassName( const char * oldname ) { int i = 0, j = 0; - static char newname [BUFSIZ]; + static char newname [BUFSIZ+1]; if( !oldname ) { return ( "" ); } @@ -221,7 +221,7 @@ const char * ENTITYget_classname( Entity ent ) { /** returns a new capitalized name, in internal static buffer */ const char * PrettyTmpName( const char * oldname ) { int i = 0; - static char newname [BUFSIZ]; + static char newname [BUFSIZ+1]; newname [0] = '\0'; while( ( oldname [i] != '\0' ) && ( i < BUFSIZ ) ) { newname [i] = ToLower( oldname [i] ); @@ -242,7 +242,7 @@ const char * PrettyTmpName( const char * oldname ) { /** This function is out of date DAS */ const char * EnumName( const char * oldname ) { int j = 0; - static char newname [MAX_LEN]; + static char newname [MAX_LEN+1]; if( !oldname ) { return ( "" ); } @@ -258,7 +258,7 @@ const char * EnumName( const char * oldname ) { const char * SelectName( const char * oldname ) { int j = 0; - static char newname [MAX_LEN]; + static char newname [MAX_LEN+1]; if( !oldname ) { return ( "" ); } @@ -274,7 +274,7 @@ const char * SelectName( const char * oldname ) { } const char * FirstToUpper( const char * word ) { - static char newword [MAX_LEN]; + static char newword [MAX_LEN+1]; strncpy( newword, word, MAX_LEN ); newword[0] = ToUpper( newword[0] ); @@ -332,7 +332,7 @@ const char * FundamentalType( const Type t, int report_reftypes ) { * the dictionary. */ const char * TypeDescriptorName( Type t ) { - static char b [BUFSIZ]; + static char b [BUFSIZ+1]; Schema parent = t->superscope; /* NOTE - I corrected a prev bug here in which the *current* schema was ** passed to this function. Now we take "parent" - the schema in which @@ -466,7 +466,7 @@ Entity ENTITYget_superclass( Entity entity ) { void ENTITYget_first_attribs( Entity entity, Linked_List result ) { Linked_List supers; - LISTdo( ENTITYget_attributes( entity ), attr, Generic ) + LISTdo( ENTITYget_attributes( entity ), attr, void * ) LISTadd_last( result, attr ); LISTod; supers = ENTITYget_supertypes( entity ); diff --git a/src/exp2python/src/classes_python.c b/src/exp2python/src/classes_python.c index 4f1876201..109efecda 100644 --- a/src/exp2python/src/classes_python.c +++ b/src/exp2python/src/classes_python.c @@ -27,13 +27,6 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7. #include #include -#ifdef __STDC__ -#include -#else -#include -#endif - -#include "sc_memmgr.h" #include "classes.h" #include "expr.h" @@ -50,10 +43,6 @@ N350 ( August 31, 1993 ) of ISO 10303 TC184/SC4/WG7. #define PAD 1 #define NOPAD 0 -#if defined( _WIN32 ) || defined ( __WIN32__ ) -# define snprintf _snprintf -#endif - int isAggregateType( const Type t ); int isAggregate( Variable a ); Variable VARis_type_shifter( Variable a ); @@ -180,7 +169,7 @@ int Handle_FedPlus_Args( int i, char * arg ) { bool is_python_keyword( char * word ) { int i; - const char* keyword_list[] = {"class", "pass", NULL}; + const char* keyword_list[] = {"class", "pass", "property", NULL}; bool python_keyword = false; for( i = 0; keyword_list[i] != NULL; i++ ) { @@ -373,9 +362,9 @@ char* EXPRto_python( Expression e ) { char * temp; unsigned int bufsize = BIGBUFSIZ; - buf = ( char * )sc_malloc( bufsize ); + buf = ( char * )malloc( bufsize ); if( !buf ) { - fprintf(stderr, "%s failed to allocate buffer: %s\n", __FUNCTION__, strerror(errno) ); + fprintf( stderr, "%s failed to allocate buffer: %s\n", __func__, strerror( errno ) ); abort(); } @@ -434,7 +423,7 @@ char* EXPRto_python( Expression e ) { snprintf( buf, bufsize, "%s.%s", TYPEget_name(e->type), e->symbol.name ); break; case query_: - strcpy( buf, "# query_ NOT_IMPLEMENTED!" ); + strcpy( buf, "SCLBase.raise_(NotImplementedError('query_'))" ); break; case self_: strcpy( buf, "self" ); @@ -456,13 +445,13 @@ char* EXPRto_python( Expression e ) { break; } case op_: - strcpy( buf, "# op_ NOT_IMPLEMENTED!" ); + strcpy( buf, "SCLBase.raise_(NotImplementedError('op_'))" ); break; case aggregate_: - strcpy( buf, "# aggregate_ NOT_IMPLEMENTED!" ); + strcpy( buf, "SCLBase.raise_(NotImplementedError('aggregate_'))" ); break; case oneof_: { - strcpy( buf, "# oneof_ NOT_IMPLEMENTED!" ); + strcpy( buf, "SCLBase.raise_(NotImplementedError('oneof_'))" ); break; } default: @@ -470,9 +459,9 @@ char* EXPRto_python( Expression e ) { abort(); } - temp = ( char * )sc_realloc( buf, 1 + strlen(buf) ); + temp = ( char * )realloc( buf, 1 + strlen(buf) ); if( temp == 0 ) { - fprintf(stderr, "%s failed to realloc buffer: %s\n", __FUNCTION__, strerror(errno) ); + fprintf( stderr, "%s failed to realloc buffer: %s\n", __func__, strerror( errno ) ); abort(); } @@ -561,7 +550,7 @@ int cmp_python_mro( void * e1, void * e2 ) { void LIBdescribe_entity( Entity entity, FILE * file ) { int attr_count_tmp = attr_count; - char attrnm [BUFSIZ], parent_attrnm[BUFSIZ]; + char attrnm [BUFSIZ+1], parent_attrnm[BUFSIZ+1]; char * attr_type; bool generate_constructor = true; /*by default, generates a python constructor */ bool single_inheritance = false; @@ -767,7 +756,7 @@ LIBdescribe_entity( Entity entity, FILE * file ) { /* if the argument is not optional */ if( !VARget_optional( v ) ) { fprintf( file, "\t\t# Mandatory argument\n" ); - fprintf( file, "\t\tassert value != None, 'Argument \"value\" is mantatory and cannot be set to None'\n" ); + fprintf( file, "\t\tassert value is not None, 'Argument \"value\" is mandatory and cannot be set to None'\n" ); fprintf( file, "\t\tif not check_type(value," ); if( TYPEis_aggregate( t ) ) { process_aggregate( file, t ); @@ -778,7 +767,7 @@ LIBdescribe_entity( Entity entity, FILE * file ) { fprintf( file, "%s):\n", attr_type ); } } else { - fprintf( file, "\t\tif value != None: # OPTIONAL attribute\n\t" ); + fprintf( file, "\t\tif value is not None: # OPTIONAL attribute\n\t" ); fprintf( file, "\t\tif not check_type(value," ); if( TYPEis_aggregate( t ) ) { process_aggregate( file, t ); @@ -789,7 +778,7 @@ LIBdescribe_entity( Entity entity, FILE * file ) { fprintf( file, "%s):\n\t", attr_type ); } } - /* check wether attr_type is aggr or explicit */ + /* check whether attr_type is aggr or explicit */ if( TYPEis_aggregate( t ) ) { fprintf( file, "\t\t\tself._%s = ", attrnm ); print_aggregate_type( file, t ); @@ -1109,6 +1098,7 @@ LOOPpyout( struct Loop_ *loop, int level, FILE * file ) { fprintf( file, "):\n" ); if( loop->while_expr ) { + python_indent( file, level + 1 ); fprintf( file, "if " ); EXPRESSION_out( loop->while_expr, 0 , file ); fprintf( file, ":\n"); @@ -1118,9 +1108,12 @@ LOOPpyout( struct Loop_ *loop, int level, FILE * file ) { } if( loop->until_expr ) { + python_indent( file, level + 1 ); fprintf( file, "if " ); EXPRESSION_out( loop->until_expr, 0 , file ); - fprintf( file, ":\n\tbreak\n"); + fprintf( file, ":\n" ); + python_indent( file, level + 2 ); + fprintf( file, "break\n" ); } } else if( loop->while_expr ) { fprintf( file, "while " ); @@ -1129,17 +1122,23 @@ LOOPpyout( struct Loop_ *loop, int level, FILE * file ) { STATEMENTlist_out( loop->statements, level + 1 , file ); if( loop->until_expr ) { + python_indent( file, level + 1 ); fprintf( file, "if " ); EXPRESSION_out( loop->until_expr, 0 , file ); - fprintf( file, ":\n\tbreak\n"); + fprintf( file, ":\n" ); + python_indent( file, level + 2 ); + fprintf( file, "break\n" ); } } else { fprintf( file, "while True:\n" ); STATEMENTlist_out( loop->statements, level + 1 , file ); + python_indent( file, level + 1 ); fprintf( file, "if " ); EXPRESSION_out( loop->until_expr, 0 , file ); - fprintf( file, ":\n\tbreak\n"); + fprintf( file, ":\n" ); + python_indent( file, level + 2 ); + fprintf( file, "break\n" ); } } @@ -1204,7 +1203,11 @@ ATTRIBUTE_INITIALIZER__out( Expression e, int paren, int previous_op , FILE * fi break; case entity_: case identifier_: - fprintf( file, "self.%s", e->symbol.name ); + if( previous_op == OP_DOT || previous_op == OP_GROUP ) { + fprintf( file, "%s", e->symbol.name ); + } else { + fprintf( file, "self.%s", e->symbol.name ); + } break; case attribute_: fprintf( file, "%s", e->symbol.name ); @@ -1424,8 +1427,8 @@ ATTRIBUTE_INITIALIZERop__out( struct Op_Subexpression* oe, int paren, Op_Code pr ATTRIBUTE_INITIALIZERop2_out( oe, " > ", paren, PAD, file ); break; case OP_IN: - /* EXPRESSIONop2_out( oe, " in ", paren, PAD, file ); */ - /* break; */ + ATTRIBUTE_INITIALIZERop2_out( oe, " in ", paren, PAD, file ); + break; case OP_INST_EQUAL: ATTRIBUTE_INITIALIZERop2_out( oe, " == ", paren, PAD, file ); break; @@ -1460,7 +1463,10 @@ ATTRIBUTE_INITIALIZERop__out( struct Op_Subexpression* oe, int paren, Op_Code pr ATTRIBUTE_INITIALIZERop2_out( oe, ".", paren, NOPAD, file ); break; case OP_GROUP: - ATTRIBUTE_INITIALIZERop2_out( oe, ".", paren, NOPAD, file ); + ATTRIBUTE_INITIALIZER_out(oe->op1, 1, file); + fprintf(file, "._scl_group("); + EXPRESSION_out(oe->op2, 0, file); + fprintf(file, ")"); break; case OP_NEGATE: ATTRIBUTE_INITIALIZERop1_out( oe, "-", paren, file ); @@ -1506,7 +1512,7 @@ EXPRESSIONop__out( struct Op_Subexpression* oe, int paren, Op_Code previous_op, EXPRESSIONop2_out( oe, " * ", paren, PAD, file ); break; case OP_XOR: - EXPRESSIONop2__out( oe, " != ", paren, PAD, previous_op, file ); + EXPRESSIONop2_out( oe, " != ", paren, PAD, file ); break; case OP_EXP: EXPRESSIONop2_out( oe, " ** ", paren, PAD, file ); @@ -1518,8 +1524,8 @@ EXPRESSIONop__out( struct Op_Subexpression* oe, int paren, Op_Code previous_op, EXPRESSIONop2_out( oe, " > ", paren, PAD, file ); break; case OP_IN: - /* EXPRESSIONop2_out( oe, " in ", paren, PAD, file ); */ - /* break; */ + EXPRESSIONop2_out( oe, " in ", paren, PAD, file ); + break; case OP_INST_EQUAL: EXPRESSIONop2_out( oe, " == ", paren, PAD, file ); break; @@ -1537,8 +1543,7 @@ EXPRESSIONop__out( struct Op_Subexpression* oe, int paren, Op_Code previous_op, EXPRESSIONop2_out( oe, " % ", paren, PAD, file ); break; case OP_NOT_EQUAL: - /*EXPRESSIONop2_out( oe, ( char * )0, paren, PAD ,file); */ - EXPRESSIONop2_out( oe, " != ", paren, PAD , file ); + EXPRESSIONop2_out( oe, " != ", paren, PAD, file ); break; case OP_NOT: EXPRESSIONop1_out( oe, " not ", paren, file ); @@ -1554,7 +1559,10 @@ EXPRESSIONop__out( struct Op_Subexpression* oe, int paren, Op_Code previous_op, EXPRESSIONop2_out( oe, ".", paren, NOPAD, file ); break; case OP_GROUP: - EXPRESSIONop2_out( oe, ".", paren, NOPAD, file ); + EXPRESSION_out(oe->op1, 1, file); + fprintf(file, "._scl_group("); + EXPRESSION_out(oe->op2, 0, file); + fprintf(file, ")"); break; case OP_NEGATE: EXPRESSIONop1_out( oe, "-", paren, file ); @@ -1583,7 +1591,7 @@ EXPRESSIONop2__out( struct Op_Subexpression * eo, char * opcode, int paren, int if( pad && paren && ( eo->op_code != previous_op ) ) { fprintf( file, "(" ); } - EXPRESSION__out( eo->op1, 1, eo->op_code , file ); + EXPRESSION__out( eo->op1, 1, OP_UNKNOWN, file ); if( pad ) { fprintf( file, " " ); } @@ -1602,7 +1610,7 @@ ATTRIBUTE_INITIALIZERop2__out( struct Op_Subexpression * eo, char * opcode, int if( pad && paren && ( eo->op_code != previous_op ) ) { fprintf( file, "(" ); } - ATTRIBUTE_INITIALIZER__out( eo->op1, 1, eo->op_code , file ); + ATTRIBUTE_INITIALIZER__out( eo->op1, 1, OP_UNKNOWN, file ); if( pad ) { fprintf( file, " " ); } @@ -1663,8 +1671,8 @@ WHEREPrint( Linked_List wheres, int level , FILE * file ) { fprintf( file, "\tdef unnamed_wr_%i(self):\n", where_rule_number ); fprintf( file, "\t\teval_unnamed_wr_%i = ", where_rule_number ); } - /*EXPRESSION_out( w->expr, level+1 , file ); */ - ATTRIBUTE_INITIALIZER_out( w->expr, level + 1 , file ); + + ATTRIBUTE_INITIALIZER_out( w->expr, level + 1, file ); /* raise exception if rule violated */ if( strcmp( w->label->name, "" ) ) { fprintf( file, "\n\t\tif not eval_%s_wr:\n", w->label->name ); @@ -1956,10 +1964,10 @@ int TYPEget_RefTypeVarNm( const Type t, char * buf, Schema schema ) { void TYPEprint_descriptions( const Type type, FILES * files, Schema schema ) { - char tdnm [BUFSIZ], - typename_buf [MAX_LEN], - base [BUFSIZ], - nm [BUFSIZ]; + char tdnm [BUFSIZ+1], + typename_buf [MAX_LEN+1], + base [BUFSIZ+1], + nm [BUFSIZ+1]; Type i; int where_rule_number = 0; @@ -1998,22 +2006,26 @@ TYPEprint_descriptions( const Type type, FILES * files, Schema schema ) { } else { fprintf( files->lib, "%s):\n", output ); } - fprintf( files->lib, "\tdef __init__(self,*kargs):\n" ); - fprintf( files->lib, "\t\tpass\n" ); - /* call the where / rules */ - LISTdo( type->where, w, Where ) - if( strcmp( w->label->name, "" ) ) { - /* define a function with the name 'label' */ - fprintf( files->lib, "\t\tself.%s()\n", w->label->name ); - } else { - /* no label */ - fprintf( files->lib, "\t\tself.unnamed_wr_%i()\n", where_rule_number ); - where_rule_number ++; + + if (LISTempty(type->where)) { + fprintf( files->lib, "\tpass\n" ); + } else { + fprintf( files->lib, "\tdef __init__(self, *args):\n" ); + /* call the where / rules */ + LISTdo( type->where, w, Where ) + if( strcmp( w->label->name, "" ) ) { + /* define a function with the name 'label' */ + fprintf( files->lib, "\t\tself.%s()\n", w->label->name ); + } else { + /* no label */ + fprintf( files->lib, "\t\tself.unnamed_wr_%i()\n", where_rule_number ); + where_rule_number ++; + } + LISTod + fprintf( files->lib, "\n" ); + /* then we process the where rules */ + WHEREPrint( type->where, 0, files->lib ); } - LISTod - fprintf( files->lib, "\n" ); - /* then we process the where rules */ - WHEREPrint( type->where, 0, files->lib ); } } else { /* TODO: cleanup, currently this is deadcode */ switch( TYPEget_body( type )->type ) { diff --git a/src/exp2python/src/classes_wrapper_python.cc b/src/exp2python/src/classes_wrapper_python.cc index d8a134779..c6842ba44 100644 --- a/src/exp2python/src/classes_wrapper_python.cc +++ b/src/exp2python/src/classes_wrapper_python.cc @@ -29,30 +29,31 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema ) { DictionaryEntry de; Type i; int redefs = 0;// index = 0; + int skipped; - /* Defined Types based on SIMPLE types */ - SCOPEdo_types( scope, t, de ) - if ( ( t->search_id == CANPROCESS ) - && !( TYPEis_enumeration( t ) || TYPEis_select( t ) || TYPEis_aggregate( t ) ) - && ( TYPEget_ancestor( t ) == NULL) ) { - TYPEprint_descriptions( t, files, schema ); - t->search_id = PROCESSED; - } - SCOPEod + while( 1 ) { + skipped = 0; - /* Defined Types with defined ancestor head - * TODO: recusive approach - */ - SCOPEdo_types( scope, t, de ) - if ( ( t->search_id == CANPROCESS ) - && !( TYPEis_enumeration( t ) || TYPEis_select( t ) || TYPEis_aggregate( t ) ) - && ( ( i = TYPEget_head( t ) ) != NULL ) ) { - if (i->search_id == PROCESSED) { + SCOPEdo_types( scope, t, de ) + if( TYPEis_enumeration( t ) || TYPEis_select( t ) || TYPEis_aggregate( t ) ) { + continue; + } + + i = TYPEget_head( t ); + if( ( !i || i->search_id == PROCESSED ) + && t->search_id == CANPROCESS ) { TYPEprint_descriptions( t, files, schema ); t->search_id = PROCESSED; + } else if( t->search_id == CANPROCESS ) { + skipped++; + } + + SCOPEod + + if( !skipped ) { + break; } } - SCOPEod /* fill in the values for the type descriptors */ /* and print the enumerations */ @@ -74,14 +75,15 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema ) { SCOPEod SCOPEdo_types( scope, t, de ) + if( TYPEis_select( t ) || TYPEis_aggregate( t ) ) { + continue; + } + // Do the non-redefined enumerations: if( ( t->search_id == CANPROCESS ) && !( TYPEis_enumeration( t ) && TYPEget_head( t ) ) ) { TYPEprint_descriptions( t, files, schema ); - if( !TYPEis_select( t ) ) { - // Selects have a lot more processing and are done below. - t->search_id = PROCESSED; - } + t->search_id = PROCESSED; } SCOPEod; @@ -101,11 +103,13 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema ) { // we don't have to worry about printing B before A. This is checked in // TYPEselect_print(). SCOPEdo_types( scope, t, de ) - if( t->search_id == CANPROCESS ) { + if( t->search_id == CANPROCESS && TYPEis_select( t ) ) { // Only selects haven't been processed yet and may still be set to // CANPROCESS. //FIXME this function is not implemented! // TYPEselect_print( t, files, schema ); + // TODO: due to conditional error we were previously executing this above without realising + TYPEprint_descriptions( t, files, schema ); t->search_id = PROCESSED; } SCOPEod; @@ -131,6 +135,14 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema ) { LISTod; LISTfree( rule_list ); + // TODO: check dependencies + SCOPEdo_types( scope, t, de ) + if( t->search_id == CANPROCESS && TYPEis_aggregate( t ) ) { + TYPEprint_descriptions( t, files, schema ); + t->search_id = PROCESSED; + } + SCOPEod + } @@ -151,7 +163,8 @@ void SCOPEPrint( Scope scope, FILES * files, Schema schema ) { ******************************************************************/ void SCHEMAprint( Schema schema, FILES * files, int suffix ) { - char schnm[MAX_LEN], sufnm[MAX_LEN], fnm[MAX_LEN], *np; + int ocnt = 0; + char schnm[MAX_LEN+1], sufnm[MAX_LEN+1], fnm[MAX_LEN+1], *np; /* sufnm = schema name + suffix */ FILE * libfile; /********** create files based on name of schema ***********/ @@ -161,9 +174,15 @@ void SCHEMAprint( Schema schema, FILES * files, int suffix ) { if( suffix == 0 ) { sprintf( sufnm, "%s", schnm ); } else { - sprintf( sufnm, "%s_%d", schnm, suffix ); + ocnt = snprintf( sufnm, MAX_LEN, "%s_%d", schnm, suffix ); + if( ocnt > MAX_LEN ) { + std::cerr << "Warning - classes_wrapper_python.cc - sufnm not large enough to hold string\n"; + } + } + ocnt = snprintf( fnm, MAX_LEN, "%s.h", sufnm ); + if( ocnt > MAX_LEN ) { + std::cerr << "Warning - classes_wrapper_python.cc - fnm not large enough to hold string\n"; } - sprintf( fnm, "%s.h", sufnm ); np = fnm + strlen( fnm ) - 1; /* point to end of constant part of string */ @@ -174,6 +193,7 @@ void SCHEMAprint( Schema schema, FILES * files, int suffix ) { } fprintf( libfile, "import sys\n" ); fprintf( libfile, "\n" ); + fprintf( libfile, "from SCL import SCLBase\n" ); fprintf( libfile, "from SCL.SCLBase import *\n" ); fprintf( libfile, "from SCL.SimpleDataTypes import *\n" ); fprintf( libfile, "from SCL.ConstructedDataTypes import *\n" ); @@ -265,7 +285,7 @@ getMCPrint( Express express, FILE * schema_h, FILE * schema_cc ) { ******************************************************************/ void EXPRESSPrint( Express express, FILES * files ) { - char fnm [MAX_LEN]; + char fnm [MAX_LEN+1]; const char * schnm; /* schnm is really "express name" */ FILE * libfile; /* new */ diff --git a/src/exp2python/src/complexSupport.h b/src/exp2python/src/complexSupport.h index 7cd781a37..7a478bbb8 100644 --- a/src/exp2python/src/complexSupport.h +++ b/src/exp2python/src/complexSupport.h @@ -116,7 +116,7 @@ class EntNode { private: MarkType mark; - char name[BUFSIZ]; + char name[BUFSIZ+1]; int multSupers; // do I correspond to an entity with >1 supertype? }; @@ -225,7 +225,7 @@ class SimpleList : public EntList { void write( ostream & ); private: - char name[BUFSIZ]; // Name of entity we correspond to. + char name[BUFSIZ+1]; // Name of entity we correspond to. MarkType I_marked; // Did I mark, and with what type of mark. }; diff --git a/src/exp2python/src/fedex_main_python.c b/src/exp2python/src/fedex_main_python.c index 9f3a39183..be7bdd242 100644 --- a/src/exp2python/src/fedex_main_python.c +++ b/src/exp2python/src/fedex_main_python.c @@ -14,6 +14,7 @@ extern void print_fedex_version( void ); static void exp2python_usage( void ) { + char *warnings_help_msg = ERRORget_warnings_help("\t", "\n"); fprintf( stderr, "usage: %s [-v] [-d # | -d 9 -l nnn -u nnn] [-n] [-p ] {-w|-i } express_file\n", EXPRESSprogram_name ); fprintf( stderr, "\t-v produces the version description below\n" ); fprintf( stderr, "\t-d turns on debugging (\"-d 0\" describes this further\n" ); @@ -21,9 +22,7 @@ static void exp2python_usage( void ) { fprintf( stderr, "\t-i warning ignore\n" ); fprintf( stderr, "and is one of:\n" ); fprintf( stderr, "\tnone\n\tall\n" ); - LISTdo( ERRORwarnings, opt, Error_Warning ) - fprintf( stderr, "\t%s\n", opt->name ); - LISTod + fprintf( stderr, "%s", warnings_help_msg); fprintf( stderr, "and is one or more of:\n" ); fprintf( stderr, " e entity\n" ); fprintf( stderr, " p procedure\n" ); diff --git a/src/exp2python/src/multpass_python.c b/src/exp2python/src/multpass_python.c index 9cc6553d3..a4204c1c8 100644 --- a/src/exp2python/src/multpass_python.c +++ b/src/exp2python/src/multpass_python.c @@ -56,7 +56,7 @@ void print_schemas_separate( Express express, FILES * files ) /* * Generates the C++ files corresponding to a list of schemas. Does so in * multiple passes through the schemas. In each pass it checks for enti- - * ties which are subtypes of entites in other schemas which have not yet + * ties which are subtypes of entities in other schemas which have not yet * been processed. Such entities cannot be processed in that pass until * their supertypes have been defined. It also checks for entities which * have enum or select attributes which have not been processed, and for @@ -150,7 +150,7 @@ void print_schemas_separate( Express express, FILES * files ) // which hasn't been closed yet. (That's done on 2nd line below.)) * / //fprintf( files->initall, "\t reg.SetCompCollect( gencomplex() );\n" ); //fprintf( files->initall, "}\n\n" ); - //fprintf( files->incall, "\n#include \n" ); + //fprintf( files->incall, "\n#include \"core/complexSupport.h\"\n" ); //fprintf( files->incall, "ComplexCollect *gencomplex();\n" ); */ /* Function GetModelContents() is printed at the end of the schema.xx @@ -498,7 +498,7 @@ static int checkItem( Type t, Scope parent, Schema schema, int * unknowncnt, parent->search_id = NOTKNOWN; /* We lower parent's value. But don't return TRUE. That // would tell checkTypes() that there's nothing more to - // check. But checkTypes should keep looping thru the re- + // check. But checkTypes should keep looping through the re- // maining items of parent - maybe one of them will tell us // that parent definitely can't be processed this pass. */ ( *unknowncnt )++; @@ -623,7 +623,7 @@ static void addUseRefNames( Schema schema, FILE * create ) Dictionary useRefDict; DictionaryEntry de; Rename * rnm; - char * oldnm, schNm[BUFSIZ]; + char * oldnm, schNm[BUFSIZ+1]; static int firsttime = TRUE; if( ( useRefDict = schema->u.schema->usedict ) != NULL ) { diff --git a/src/exp2python/src/selects_python.c b/src/exp2python/src/selects_python.c index 3579849e5..2bc45d151 100644 --- a/src/exp2python/src/selects_python.c +++ b/src/exp2python/src/selects_python.c @@ -23,7 +23,7 @@ extern int multiple_inheritance; **************************************************************************/ #include #include "classes.h" -#include +#include bool is_python_keyword( char * word ); int isAggregateType( const Type t ); @@ -81,8 +81,8 @@ LISTmember determines if the given entity is a member of the list. RETURNS the member if it is a member; otherwise 0 is returned. *******************/ -Generic -LISTmember( const Linked_List list, Generic e ) { +void * +LISTmember( const Linked_List list, void *e ) { Link node; for( node = list->mark->next; node != list->mark; node = node->next ) if( e == node -> data ) { @@ -146,7 +146,7 @@ compareOrigTypes( Type a, Type b ) { *******************/ const char * utype_member( const Linked_List list, const Type check, int rename ) { - static char r [BUFSIZ]; + static char r [BUFSIZ+1]; LISTdo( list, t, Type ) strncpy( r, TYPEget_utype( t ), BUFSIZ ); @@ -246,7 +246,7 @@ determines if the given "link's" C++ representation is used again in the list. *******************/ int duplicate_utype_member( const Linked_List list, const Type check ) { - char b [BUFSIZ]; + char b [BUFSIZ+1]; if( TYPEis_entity( check ) ) { return FALSE; @@ -414,7 +414,7 @@ non_unique_types_string( const Type type ) { non_unique_types_vector( type, tvec ); /* build type string from vector */ - typestr = ( char * )malloc( BUFSIZ ); + typestr = ( char * )malloc( BUFSIZ+1 ); typestr[0] = '\0'; strcat( typestr, ( char * )"(" ); for( i = 0; i <= tnumber; i++ ) { @@ -475,8 +475,8 @@ non_unique_types_string( const Type type ) { Variable ATTR_LISTmember( Linked_List l, Variable check ) { - char nm [BUFSIZ]; - char cur [BUFSIZ]; + char nm [BUFSIZ+1]; + char cur [BUFSIZ+1]; generate_attribute_name( check, nm ); LISTdo( l, a, Variable ) diff --git a/src/exppp/CMakeLists.txt b/src/exppp/CMakeLists.txt index b52821325..0eada170b 100644 --- a/src/exppp/CMakeLists.txt +++ b/src/exppp/CMakeLists.txt @@ -26,18 +26,23 @@ SET(EXPPP_SOURCES include_directories( ${SC_SOURCE_DIR}/include ${SC_SOURCE_DIR}/include/exppp - ${SC_SOURCE_DIR}/src/base ${SC_SOURCE_DIR}/src/express ) -if(BORLAND) - add_definitions(-D__STDC__) +if(BUILD_SHARED_LIBS) + SC_ADDLIB(libexppp SHARED SOURCES ${LIBEXPPP_SOURCES} LINK_LIBRARIES express) + set_target_properties(libexppp PROPERTIES PREFIX "") + if(WIN32) + target_compile_definitions(libexppp PRIVATE SC_EXPPP_DLL_EXPORTS) + endif() endif() -SC_ADDLIB(libexppp "${LIBEXPPP_SOURCES}" "express;base") -set_target_properties(libexppp PROPERTIES PREFIX "") +if(BUILD_STATIC_LIBS) + SC_ADDLIB(libexppp-static STATIC SOURCES ${LIBEXPPP_SOURCES} LINK_LIBRARIES express-static) + set_target_properties(libexppp-static PROPERTIES PREFIX "") +endif() -SC_ADDEXEC(exppp "${EXPPP_SOURCES}" "libexppp;express;base") +SC_ADDEXEC(exppp SOURCES ${EXPPP_SOURCES} LINK_LIBRARIES libexppp express) if(SC_ENABLE_TESTING) add_subdirectory(test) diff --git a/src/exppp/exppp-main.c b/src/exppp/exppp-main.c index 079f0885d..670dd7a88 100644 --- a/src/exppp/exppp-main.c +++ b/src/exppp/exppp-main.c @@ -4,6 +4,7 @@ #include "exppp.h" static void exppp_usage( void ) { + char *warnings_help_msg = ERRORget_warnings_help("\t", "\n"); fprintf( stderr, "usage: %s [-v] [-d #] [-p ] {-w|-i } [-l ] [-c] [-o [file|--]] express_file\n", EXPRESSprogram_name ); fprintf( stderr, "\t-v produces a version description\n" ); fprintf( stderr, "\t-l specifies line length hint for output\n" ); @@ -16,9 +17,7 @@ static void exppp_usage( void ) { fprintf( stderr, "\t-i warning ignore\n" ); fprintf( stderr, "and is one of:\n" ); fprintf( stderr, "\tnone\n\tall\n" ); - LISTdo( ERRORwarnings, opt, Error_Warning ) - fprintf( stderr, "\t%s\n", opt->name ); - LISTod + fprintf( stderr, "%s", warnings_help_msg); fprintf( stderr, "and is one or more of:\n" ); fprintf( stderr, " e entity\n" ); fprintf( stderr, " p procedure\n" ); diff --git a/src/exppp/exppp.c b/src/exppp/exppp.c index 39a213048..ff929e57d 100644 --- a/src/exppp/exppp.c +++ b/src/exppp/exppp.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -13,11 +12,6 @@ #include "pp.h" #include "exppp.h" - -#if defined( _WIN32 ) || defined ( __WIN32__ ) -# define snprintf _snprintf -#endif - /* PP_SMALL_BUF_SZ is a macro used in a few places where const int causes * "warning: ISO C90 forbids variable length array 'buf' [-Wvla]" * @@ -214,9 +208,6 @@ void exppp_init() { return; } first_time = false; - - ERROR_select_empty = ERRORcreate( - "select type %s has no members", SEVERITY_ERROR ); } @@ -437,7 +428,7 @@ int prep_string() { } string_func_in_use = true; - exppp_buf = exppp_bufp = ( char * )sc_malloc( BIGBUFSIZ ); + exppp_buf = exppp_bufp = ( char * )malloc( BIGBUFSIZ + 1 ); if( !exppp_buf ) { fprintf( stderr, "failed to allocate exppp buffer\n" ); return 1; @@ -455,7 +446,7 @@ int prep_string() { } char * finish_string() { - char * b = ( char * )sc_realloc( exppp_buf, 1 + exppp_maxbuflen - exppp_buflen ); + char * b = ( char * )realloc( exppp_buf, 1 + exppp_maxbuflen - exppp_buflen ); if( b == 0 ) { fprintf( stderr, "failed to reallocate exppp buffer\n" ); diff --git a/src/exppp/pp.h b/src/exppp/pp.h index 89825de6a..a441fece9 100644 --- a/src/exppp/pp.h +++ b/src/exppp/pp.h @@ -4,7 +4,7 @@ #ifndef PP_H #define PP_H -#include +#include #include extern int indent2; /**< where continuation lines start */ diff --git a/src/exppp/pretty_expr.c b/src/exppp/pretty_expr.c index 60a1c2ded..1b9aeda7b 100644 --- a/src/exppp/pretty_expr.c +++ b/src/exppp/pretty_expr.c @@ -4,7 +4,7 @@ */ #include -#include +#include #include #include "exppp.h" diff --git a/src/exppp/pretty_ref.c b/src/exppp/pretty_ref.c index cbb65c3ff..3d73efd77 100644 --- a/src/exppp/pretty_ref.c +++ b/src/exppp/pretty_ref.c @@ -33,10 +33,9 @@ void REFout( Dictionary refdict, Linked_List reflist, char * type, int level ) { nameList = ( Linked_List )DICTlookup( dict, ren->schema->symbol.name ); if( !nameList ) { nameList = LISTcreate(); - DICTdefine( dict, ren->schema->symbol.name, ( Generic ) nameList, - ( Symbol * )0, OBJ_UNKNOWN ); + DICTdefine( dict, ren->schema->symbol.name, nameList, NULL, OBJ_UNKNOWN ); } - LISTadd_last( nameList, ( Generic ) ren ); + LISTadd_last( nameList, ren ); } /* step 2: for each list, print out the renames */ diff --git a/src/exppp/pretty_schema.c b/src/exppp/pretty_schema.c index ba43f821a..c17ebe5be 100644 --- a/src/exppp/pretty_schema.c +++ b/src/exppp/pretty_schema.c @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -14,7 +13,7 @@ #include "pretty_scope.h" #include "pretty_schema.h" -#if defined( _WIN32 ) || defined ( __WIN32__ ) +#ifdef _WIN32 # define unlink _unlink #else # include /* for unlink */ @@ -77,7 +76,7 @@ char * SCHEMAout( Schema s ) { if( 0 != ( p = strchr( buf, '\n' ) ) ) { *p = '\0'; } - if( ( !result ) || ( streq( buf, expheader[0] ) ) ) { + if( ( !result ) || ( !strcmp( buf, expheader[0] ) ) ) { unlink( exppp_filename_buffer ); } else { fprintf( stderr, "%s: %s already exists and appears to be hand-written\n", @@ -99,7 +98,7 @@ char * SCHEMAout( Schema s ) { fprintf( stdout, "%s: writing schema file %s\n", EXPRESSprogram_name, exppp_filename_buffer ); } if( !( exppp_fp = f = fopen( exppp_filename_buffer, "w" ) ) ) { - ERRORreport( ERROR_file_unwriteable, exppp_filename_buffer, strerror( errno ) ); + ERRORreport( FILE_UNWRITABLE, exppp_filename_buffer, strerror( errno ) ); return 0; } } @@ -108,7 +107,7 @@ char * SCHEMAout( Schema s ) { for( hp = expheader; *hp; hp++ ) { if( ( **hp == '\0' ) && ( **( hp + 1 ) == '\0' ) ) { /* if this and the next lines are blank, put version string on this line */ - raw( "%s\n", sc_version ); + raw( "%s\n", SC_VERSION ); } else { raw( "%s\n", *hp ); } diff --git a/src/exppp/pretty_scope.c b/src/exppp/pretty_scope.c index 1fccdc73f..85fe041d1 100644 --- a/src/exppp/pretty_scope.c +++ b/src/exppp/pretty_scope.c @@ -24,7 +24,7 @@ void SCOPEadd_inorder( Linked_List list, Scope s ) { break; } LISTod - LISTadd_before( list, k, ( Generic )s ); + LISTadd_before( list, k, s ); } /** like SCOPEadd_inorder, but for Variables */ @@ -37,7 +37,7 @@ void SCOPEaddvars_inorder( Linked_List list, Variable v ) { break; } LISTod - LISTadd_before( list, k, ( Generic )v ); + LISTadd_before( list, k, v ); } @@ -244,11 +244,11 @@ void SCOPEconsts_out( Scope s, int level ) { void SCOPElocals_order( Linked_List list, Variable v ) { LISTdo_links( list, link ) { if( v->offset < ( (Variable) link->data )->offset ) { - LISTadd_before( list, link, (Generic) v ); + LISTadd_before( list, link, v ); return; } } LISTod - LISTadd_last( list, (Generic) v ); + LISTadd_last( list, v ); } void SCOPElocals_out( Scope s, int level ) { @@ -290,7 +290,7 @@ void SCOPElocals_out( Scope s, int level ) { } if( !orderedLocals ) { orderedLocals = LISTcreate(); - LISTadd_first( orderedLocals, (Generic) v ); + LISTadd_first( orderedLocals, v ); } else { /* sort by v->offset */ SCOPElocals_order( orderedLocals, v ); diff --git a/src/exppp/pretty_subtype.c b/src/exppp/pretty_subtype.c index d47298e49..f21d6c620 100644 --- a/src/exppp/pretty_subtype.c +++ b/src/exppp/pretty_subtype.c @@ -2,8 +2,6 @@ * split out of exppp.c 9/21/13 */ -#include - #include "exppp.h" #include "pp.h" diff --git a/src/exppp/pretty_type.c b/src/exppp/pretty_type.c index d4cf62fb7..678d2b87a 100644 --- a/src/exppp/pretty_type.c +++ b/src/exppp/pretty_type.c @@ -5,7 +5,6 @@ #include #include -#include #include "exppp.h" #include "pp.h" @@ -151,7 +150,7 @@ void TYPE_body_out( Type t, int level ) { while( 0 != ( expr = ( Expression )DICTdo( &de ) ) ) { count++; } - names = ( char ** )sc_malloc( count * sizeof( char * ) ); + names = ( char ** )calloc( count, sizeof( char * ) ); DICTdo_type_init( t->symbol_table, &de, OBJ_EXPRESSION ); while( 0 != ( expr = ( Expression )DICTdo( &de ) ) ) { names[expr->u.integer - 1] = expr->symbol.name; @@ -175,7 +174,7 @@ void TYPE_body_out( Type t, int level ) { raw( names[i] ); } raw( " )" ); - sc_free( ( char * )names ); + free( ( char * )names ); } break; case select_: @@ -198,7 +197,7 @@ void TYPE_body_out( Type t, int level ) { /* if empty, force a left paren */ if( first_time ) { - ERRORreport_with_symbol( ERROR_select_empty, &error_sym, t->symbol.name ); + ERRORreport_with_symbol( SELECT_EMPTY, &error_sym, t->symbol.name ); raw( "%*s( ", level, "" ); } raw( " )" ); diff --git a/src/exppp/test/CMakeLists.txt b/src/exppp/test/CMakeLists.txt index f99c932af..e13a480e0 100644 --- a/src/exppp/test/CMakeLists.txt +++ b/src/exppp/test/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.12) project(test_exppp) set(breakLongStr_SRCS @@ -14,7 +14,7 @@ add_test(NAME build_exppp ) # this executable doesn't really check the results, just ensures no segfaults. ought to improve it... -SC_ADDEXEC(tst_breakLongStr "${breakLongStr_SRCS}" "express;base" "TESTABLE") +SC_ADDEXEC(tst_breakLongStr SOURCES ${breakLongStr_SRCS} LINK_LIBRARIES express TESTABLE) add_test(NAME build_tst_breakLongStr WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} --build . diff --git a/src/exppp/test/exppp_div_slash.cmake b/src/exppp/test/exppp_div_slash.cmake index 3c81b6860..5e11a92a0 100644 --- a/src/exppp/test/exppp_div_slash.cmake +++ b/src/exppp/test/exppp_div_slash.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 2.8 ) +cmake_minimum_required( VERSION 3.12 ) # executable is ${EXPPP}, input file is ${INFILE} diff --git a/src/exppp/test/exppp_lost_var.cmake b/src/exppp/test/exppp_lost_var.cmake index d564d7f1b..1989cc465 100644 --- a/src/exppp/test/exppp_lost_var.cmake +++ b/src/exppp/test/exppp_lost_var.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 2.8 ) +cmake_minimum_required( VERSION 3.12 ) # executable is ${EXPPP}, input file is ${INFILE} diff --git a/src/exppp/test/inverse_qualifiers.cmake b/src/exppp/test/inverse_qualifiers.cmake index c27b473a7..48f1fc5ea 100644 --- a/src/exppp/test/inverse_qualifiers.cmake +++ b/src/exppp/test/inverse_qualifiers.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 2.8 ) +cmake_minimum_required( VERSION 3.12 ) # executable is ${EXPPP}, input file is ${INFILE} @@ -13,7 +13,7 @@ endif( NOT ${CMD_RESULT} EQUAL 0 ) file( READ ${ofile} pretty_out LIMIT 1024 ) # SELF\product_occurrence.occurrence_contexts : SET [1 : ?] OF assembly_component_relationship FOR related_view; -# one backslash baloons into 4 x( +# one backslash balloons into 4 x( string( REGEX MATCH " *SELF *\\\\ *product_occurrence *\\. *occurrence_contexts *: *SET *\\[ *1 *:" match_result ${pretty_out} ) if( match_result STREQUAL "" ) diff --git a/src/exppp/test/unique_qualifiers.cmake b/src/exppp/test/unique_qualifiers.cmake index 8bf492d2f..812793d94 100644 --- a/src/exppp/test/unique_qualifiers.cmake +++ b/src/exppp/test/unique_qualifiers.cmake @@ -1,4 +1,4 @@ -cmake_minimum_required( VERSION 2.8 ) +cmake_minimum_required( VERSION 3.12 ) # executable is ${EXPPP}, input file is ${INFILE} @@ -13,7 +13,7 @@ endif( NOT ${CMD_RESULT} EQUAL 0 ) file( READ ${ofile} pretty_out LIMIT 1024 ) # ur1 : SELF\shape_aspect_relationship.name; -# one backslash baloons into 4, and I can't figure out how to escape the semicolon x( +# one backslash balloons into 4, and I can't figure out how to escape the semicolon x( string( REGEX MATCH "[uU][rR]1 *: *SELF *\\\\ *shape_aspect_relationship *\\. *name" match_result ${pretty_out} ) if( match_result STREQUAL "" ) diff --git a/src/express/CMakeLists.txt b/src/express/CMakeLists.txt index a63f2aa93..e5c0dfe04 100644 --- a/src/express/CMakeLists.txt +++ b/src/express/CMakeLists.txt @@ -1,70 +1,37 @@ include_directories( - ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR} - ${SC_SOURCE_DIR}/src/base ) -# Set up the information we need to feed the generated source management -# scripts -set(BASELINE_INFORMATION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/generated/verification_info.cmake") -set(PROJECT_CMAKE_DIR "${SC_SOURCE_DIR}/cmake") -set(MD5_FILELIST - "${CMAKE_CURRENT_SOURCE_DIR}/expscan.l" - "${CMAKE_CURRENT_SOURCE_DIR}/expparse.y" - "${CMAKE_CURRENT_SOURCE_DIR}/generated/expscan.c" - "${CMAKE_CURRENT_SOURCE_DIR}/generated/expscan.h" - "${CMAKE_CURRENT_SOURCE_DIR}/generated/expparse.c" - "${CMAKE_CURRENT_SOURCE_DIR}/generated/expparse.h" - ) -configure_file(${SC_SOURCE_DIR}/cmake/md5_gen.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/express_md5gen.cmake @ONLY) -configure_file(${SC_SOURCE_DIR}/cmake/md5_verify.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/express_verify.cmake @ONLY) - -# Convenience target to generate an updated verification_info.cmake file -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/express_md5gen.sentinel - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/express_md5gen.cmake - COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/express_md5gen.sentinel - ) -add_custom_target(express_md5gen DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/express_md5gen.sentinel) - -# Target for actually checking cached MD5 sums against files -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/express_verify.sentinel - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/express_verify.cmake - COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/express_verify.sentinel - DEPENDS ${MD5_FILELIST} - ) -add_custom_target(express_verify DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/express_verify.sentinel) - - # Depending on whether we're using pre-generated sources or building them on # the fly, set up targets and source lists. if(SC_GENERATE_LP_SOURCES) - LEMON_TARGET(ExpParser expparse.y) + LEMON_TARGET(ExpParser expparse.y expparse.c + COMPILE_FLAGS "-p -c" + DEFINES_FILE "expparse.h" + ) PERPLEX_TARGET(ExpScanner expscan.l) ADD_PERPLEX_LEMON_DEPENDENCY(ExpScanner ExpParser) - set(SCL_SO_SRCS - ${LEMON_ExpParser_SRC} - ${PERPLEX_ExpScanner_SRC} - ) - LEMON_TARGET(ExpParser_static expparse.y) - PERPLEX_TARGET(ExpScanner_static expscan.l) - ADD_PERPLEX_LEMON_DEPENDENCY(ExpScanner_static ExpParser_static) - set(SCL_STATIC_SRCS - ${LEMON_ExpParser_static_SRC} - ${PERPLEX_ExpScanner_static_SRC} - ) + add_library(objlib_expscan_c OBJECT ${PERPLEX_ExpScanner_SRC}) + set_property(TARGET objlib_expscan_c PROPERTY POSITION_INDEPENDENT_CODE ON) + + add_library(objlib_expparse_c OBJECT ${LEMON_ExpParser_OUTPUTS}) + set_property(TARGET objlib_expparse_c PROPERTY POSITION_INDEPENDENT_CODE ON) + set_source_files_properties(${LEMON_ExpParser_OUTPUTS} PROPERTIES OBJECT_DEPENDS "${PERPLEX_ExpScanner_HDR}") + else(SC_GENERATE_LP_SOURCES) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}/generated) - set(EXPRESS_GENERATED_SRCS - generated/expparse.c - generated/expscan.c - ) - set(SCL_SO_SRCS ${EXPRESS_GENERATED_SRCS}) - set(SCL_STATIC_SRCS ${EXPRESS_GENERATED_SRCS}) + add_subdirectory(generated) + include_directories(generated) endif(SC_GENERATE_LP_SOURCES) +if(MSVC) + set_property(TARGET objlib_expscan_c APPEND PROPERTY COMPILE_DEFINITIONS "SC_EXPRESS_DLL_EXPORTS") + set_property(TARGET objlib_expscan_c APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "SC_EXPRESS_DLL_IMPORTS") + set_property(TARGET objlib_expparse_c APPEND PROPERTY COMPILE_DEFINITIONS "SC_EXPRESS_DLL_EXPORTS") + set_property(TARGET objlib_expparse_c APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "SC_EXPRESS_DLL_IMPORTS") +endif(MSVC) + set(EXPRESS_SOURCES symbol.c type.c @@ -77,18 +44,81 @@ set(EXPRESS_SOURCES scope.c schema.c resolve.c + resolve2.c lexact.c linklist.c error.c dict.c hash.c + alloc.c memory.c object.c express.c ordered_attrs.cc info.c - exp_kw.c - ) + factory.c + ) + +set(EXPRESS_OBJS) +foreach(_src ${EXPRESS_SOURCES}) + string(REPLACE "." "_" _suffix ${_src}) + set(_objlib "objlib_${_suffix}") + add_library(${_objlib} OBJECT ${_src}) + add_dependencies(${_objlib} objlib_expscan_c) + add_dependencies(${_objlib} objlib_expparse_c) + if(TARGET ExpScanner) + add_dependencies(${_objlib} ExpScanner) + endif(TARGET ExpScanner) + if(MSVC) + set_property(TARGET ${_objlib} APPEND PROPERTY COMPILE_DEFINITIONS "SC_EXPRESS_DLL_EXPORTS") + set_property(TARGET ${_objlib} APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "SC_EXPRESS_DLL_IMPORTS") + endif(MSVC) + # TODO: probably PIC should be used everywhere... + set_property(TARGET ${_objlib} PROPERTY POSITION_INDEPENDENT_CODE ON) + list(APPEND EXPRESS_OBJS $) +endforeach() + +list(APPEND EXPRESS_OBJS $) +list(APPEND EXPRESS_OBJS $) + + +if(SC_GENERATE_LP_SOURCES) + set_property(TARGET objlib_expparse_c objlib_express_c objlib_lexact_c + APPEND PROPERTY INCLUDE_DIRECTORIES "${PERPLEX_ExpScanner_INCLUDE_DIR}") + set_property(TARGET objlib_expscan_c objlib_express_c objlib_lexact_c + APPEND PROPERTY INCLUDE_DIRECTORIES "${LEMON_ExpParser_INCLUDE_DIR}") + # OBJECT libraries are not targets, and so an explicit dependency is required + set_source_files_properties(express.c lexact.c PROPERTIES OBJECT_DEPENDS "${PERPLEX_ExpScanner_HDR};${LEMON_ExpParser_HDR}") +endif() + +if(BUILD_SHARED_LIBS OR NOT BUILD_STATIC_LIBS) + add_library(express SHARED ${EXPRESS_OBJS}) + if(OPENBSD) + set_target_properties(express PROPERTIES VERSION ${SC_VERSION_MAJOR}.${SC_VERSION_MINOR}) + else(OPENBSD) + set_target_properties(express PROPERTIES VERSION ${SC_VERSION} SOVERSION ${SC_VERSION_MAJOR}) + endif(OPENBSD) + if(APPLE) + set_property(TARGET express APPEND PROPERTY LINK_FLAGS "-flat_namespace -undefined suppress") + endif(APPLE) + install(TARGETS express + RUNTIME DESTINATION ${BIN_DIR} + LIBRARY DESTINATION ${LIB_DIR} + ARCHIVE DESTINATION ${LIB_DIR}) + + if(MSVC) + set_property(TARGET express APPEND PROPERTY COMPILE_DEFINITIONS "SC_EXPRESS_DLL_EXPORTS") + set_property(TARGET express APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "SC_EXPRESS_DLL_IMPORTS") + endif(MSVC) +endif() + +if(BUILD_STATIC_LIBS) + add_library(express-static STATIC ${EXPRESS_OBJS}) + install(TARGETS express-static + RUNTIME DESTINATION ${BIN_DIR} + LIBRARY DESTINATION ${LIB_DIR} + ARCHIVE DESTINATION ${LIB_DIR}) +endif() # TODO # Currently, fedex.c provides the main() for multiple programs. These programs @@ -102,35 +132,18 @@ set(EXPRESS_SOURCES set(CHECK_EXPRESS_SOURCES fedex.c inithook.c - ) - -SET(EXPRESS_PRIVATE_HDRS - exptoks.h - stack.h ) -SC_ADDLIB(express "${EXPRESS_SOURCES}" "base" SO_SRCS "${SCL_SO_SRCS}" STATIC_SRCS "${SCL_STATIC_SRCS}") -if(SC_GENERATE_LP_SOURCES) - set_property(TARGET express APPEND PROPERTY INCLUDE_DIRECTORIES "${PERPLEX_ExpScanner_INCLUDE_DIR}") - set_property(TARGET express APPEND PROPERTY INCLUDE_DIRECTORIES "${LEMON_ExpParser_INCLUDE_DIR}") - if (TARGET express-static) - set_property(TARGET express-static APPEND PROPERTY INCLUDE_DIRECTORIES "${PERPLEX_ExpScanner_static_INCLUDE_DIR}") - set_property(TARGET express-static APPEND PROPERTY INCLUDE_DIRECTORIES "${LEMON_ExpParser_static_INCLUDE_DIR}") - endif (TARGET express-static) -endif(SC_GENERATE_LP_SOURCES) - -if(SC_GENERATE_LP_SOURCES) - add_custom_command(TARGET express POST_BUILD - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/express_verify.cmake - ) -else(SC_GENERATE_LP_SOURCES) - add_dependencies(express express_verify) -endif(SC_GENERATE_LP_SOURCES) - -if(NOT SC_IS_SUBBUILD AND SC_GIT_VERSION) - add_dependencies(express version_string) -endif(NOT SC_IS_SUBBUILD AND SC_GIT_VERSION) -SC_ADDEXEC("check-express" "${CHECK_EXPRESS_SOURCES}" "express;base" ${SC_EXEC_NOINSTALL}) +add_executable(check-express ${CHECK_EXPRESS_SOURCES}) +if(BUILD_SHARED_LIBS OR NOT BUILD_STATIC_LIBS) + target_link_libraries(check-express express) +else() + target_link_libraries(check-express express-static) +endif() +install(TARGETS check-express + RUNTIME DESTINATION ${BIN_DIR} + LIBRARY DESTINATION ${LIB_DIR} + ARCHIVE DESTINATION ${LIB_DIR}) if(SC_ENABLE_TESTING) add_subdirectory(test) diff --git a/src/express/Changes b/src/express/Changes index e7d4c5488..be48e6205 100644 --- a/src/express/Changes +++ b/src/express/Changes @@ -158,7 +158,7 @@ Class x; -> Class_of_what x; i.e., Class_of_Type x; -Similary, OBJget_class is now specific to whatever class you are using. +Similarly, OBJget_class is now specific to whatever class you are using. I.e., @@ -496,7 +496,7 @@ foreach schema Original code did not check for redefining keywords. Fixed. ====================================================================== USE and REFERENCE are handled by having separate lists and -dictionaries to remember schemas and invididual objects that are USEd +dictionaries to remember schemas and individual objects that are USEd and REFd. 'rename' structures are used to point to the remote object. (This avoids the need for copying dictionaries, which enabled large time/space savings.) diff --git a/src/express/README b/src/express/README index 34c0b9921..30774388e 100644 --- a/src/express/README +++ b/src/express/README @@ -41,7 +41,7 @@ them. I expect this should run on any UNIX, POSIX, or other system using a compatibility package. For instance, you can build this on a PC -runing DOS using djgpp (GNU C on DOS). (Ask your local archie server +running DOS using djgpp (GNU C on DOS). (Ask your local archie server where to get djgpp.) -------------------- diff --git a/src/express/alg.c b/src/express/alg.c index 4d010f509..2211eff1a 100644 --- a/src/express/alg.c +++ b/src/express/alg.c @@ -38,7 +38,6 @@ * prettied up interface to print_objects_when_running */ -#include #include "express/alg.h" #include "express/object.h" #include "express/schema.h" @@ -73,20 +72,8 @@ Scope ALGcreate( char type ) { ** Description: Initialize the Algorithm module. */ -Symbol * WHERE_get_symbol( Generic w ) { - return( ( ( Where )w )->label ); -} - /** Initialize the Algorithm module. */ void ALGinitialize( void ) { - MEMinitialize( &FUNC_fl, sizeof( struct Function_ ), 100, 50 ); - MEMinitialize( &RULE_fl, sizeof( struct Rule_ ), 100, 50 ); - MEMinitialize( &PROC_fl, sizeof( struct Procedure_ ), 100, 50 ); - MEMinitialize( &WHERE_fl, sizeof( struct Where_ ), 100, 50 ); - OBJcreate( OBJ_RULE, SCOPE_get_symbol, "rule", OBJ_UNUSED_BITS ); - OBJcreate( OBJ_PROCEDURE, SCOPE_get_symbol, "procedure", OBJ_PROCEDURE_BITS ); - OBJcreate( OBJ_FUNCTION, SCOPE_get_symbol, "function", OBJ_FUNCTION_BITS ); - OBJcreate( OBJ_WHERE, WHERE_get_symbol, "where", OBJ_WHERE_BITS ); } void ALGput_full_text( Scope s, int start, int end ) { diff --git a/src/express/alloc.c b/src/express/alloc.c new file mode 100644 index 000000000..e20cfa943 --- /dev/null +++ b/src/express/alloc.c @@ -0,0 +1,214 @@ +/* alloc.c - memory allocator for fixed size blocks */ + +/* + +This code is replacement for malloc() and free(). It takes advantage +of the fact that all of my memory allocation is of known fixed-size +blocks. This particular implementation, however, is extremely general +and will do allocation of any number of different fixed-size blocks. + +I will just give a simple example here. To allocate struct foo's, declare a handle to the foo space as: + + struct freelist_head foo_freelist; + +Initialize it: + + memory_init(&foo_freelist,sizeof(struct foo),1000,200); + +Here we have asked for an initial allocation of 1000 foo's. When that +runs out, further allocations will automatically be performed 200 +foo's at a time. (Each allocation calls sbrk() so you want to +minimize them.) + +To actually allocate and deallocate foo's, it helps to define two +macros as follow: + + #define foo_new() (struct foo *)new(&foo_freelist) + #define foo_destroy(x) destroy(&oct_freelist_head,(Freelist *)(char *)x) + +Now you can say things like: + + foo1 = foo_new(); + foo_destroy(foo1); + +*/ + +#include +#include + +#include "express/alloc.h" +#include "express/error.h" + +/* just in case we are compiling by hand */ +#ifndef ALLOC +#define ALLOC +#endif /*ALLOC*/ + +/** chop up big block into linked list of small blocks + * return 0 for failure + * \param flh freelist head + * \param bytes new memory size + */ +Freelist * create_freelist( struct freelist_head * flh, int bytes ) { + Freelist * current = ( Freelist * )malloc( bytes ); + if( current == 0 ) { + return( 0 ); + } + + flh->freelist = current; + +#ifndef NOSTAT + flh->create++; + + /* set max to point to end of freelist */ + if( ( char * )flh->freelist + bytes > ( char * )flh->max ) { + flh->max = ( char * )flh->freelist + bytes; + } +#endif + + while( ( char * )current + flh->size < + ( ( char * )flh->freelist + bytes ) ) { + current->next = ( Freelist * )( ¤t->memory + flh->size ); + current = current->next; + } + current->next = NULL; + return( current ); +} + +void +_ALLOCinitialize() { +#ifdef DEBUG_MALLOC + malloc_debug( 2 ); +#endif +} + +/** + * \param flh freelist head + * \param size size of a single element + * \param alloc1 number to allocate initially + * \param alloc2 number to allocate if we run out + */ +void ALLOCinitialize( struct freelist_head * flh, unsigned int size, int alloc1, int alloc2 ) { + flh->size_elt = size; /* kludge for calloc-like behavior */ +#ifndef NOSTAT + flh->alloc = flh->dealloc = flh->create = 0; + flh->max = 0; +#endif + + /* make block large enough to hold the linked list pointer */ + flh->size = ( size > sizeof( Freelist * ) ? size : sizeof( Freelist * ) ); + /* set up for future allocations */ + flh->bytes = flh->size * alloc2; + +#ifdef REAL_MALLOC + return; + /*NOTREACHED*/ +#else + if( 0 == create_freelist( flh, flh->size * alloc1 ) ) { + ERRORnospace(); + } + +#ifdef SPACE_PROFILE + flh->count = 0; +#endif /*SPACE_PROFILE*/ + +#endif +} + +void * ALLOC_new( struct freelist_head * flh ) { + void *obj; + +#ifndef NOSTAT + flh->alloc++; +#endif + +#ifdef REAL_MALLOC + return( calloc( 1, flh->size_elt ) ); + /*NOTREACHED*/ +#else + if( flh->freelist == NULL && 0 == create_freelist( flh, flh->bytes ) ) { + ERRORnospace(); + } + + obj = &flh->freelist->memory; + flh->freelist = flh->freelist->next; + +#ifndef NOSTAT + if( obj > flh->max ) { + abort(); + } +#endif + +#ifdef SPACE_PROFILE + flh->count++; +#endif /*SPACE_PROFILE*/ + + /* calloc-like */ + memset( obj, 0, flh->size_elt ); + + return( obj ); +#endif +} + +void ALLOC_destroy( struct freelist_head * flh, Freelist * link ) { +#ifndef NOSTAT + flh->dealloc++; +#endif + +#ifdef REAL_MALLOC + free( link ); + return; + /*NOTREACHED*/ +#else + + link->next = flh->freelist; + flh->freelist = link; + +#ifdef SPACE_PROFILE + flh->count--; +#endif /*SPACE_PROFILE*/ + +#endif +} + +#ifdef ALLOC_MAIN +struct freelist_head oct_freelist; + +#define new_oct() (struct oct *)new(&oct_freelist) +#define destroy_oct(oct) (destroy(&oct_freelist,(Freelist *)(char *)oct)) + +struct oct { + char a[16]; +}; + +main() { + struct oct * o1, *o2, *o3, *o4, *o5, *o6; + + memory_init( &oct_freelist, sizeof( struct oct ), 5, 2 ); + + o1 = new_oct(); + fprintf( stderr, "o1 = %x\n", o1 ); + o2 = new_oct(); + fprintf( stderr, "o2 = %x\n", o2 ); + o3 = new_oct(); + fprintf( stderr, "o3 = %x\n", o3 ); + o4 = new_oct(); + fprintf( stderr, "o4 = %x\n", o4 ); + o5 = new_oct(); + fprintf( stderr, "o5 = %x\n", o5 ); + o6 = new_oct(); + fprintf( stderr, "o6 = %x\n", o6 ); + destroy_oct( o1 ); + destroy_oct( o2 ); + o1 = new_oct(); + fprintf( stderr, "o1 = %x\n", o1 ); + o2 = new_oct(); + fprintf( stderr, "o2 = %x\n", o2 ); + o3 = new_oct(); + fprintf( stderr, "o3 = %x\n", o3 ); + o4 = new_oct(); + fprintf( stderr, "o4 = %x\n", o4 ); + o5 = new_oct(); + fprintf( stderr, "o5 = %x\n", o5 ); +} +#endif /*ALLOC_MAIN*/ diff --git a/src/express/caseitem.c b/src/express/caseitem.c index 6082cc755..fe8aa460f 100644 --- a/src/express/caseitem.c +++ b/src/express/caseitem.c @@ -29,15 +29,12 @@ * prettied up interface to print_objects_when_running */ -#include #include "express/caseitem.h" -struct freelist_head CASE_IT_fl; /** Initialize the Case Item module. */ void CASE_ITinitialize( void ) { - MEMinitialize( &CASE_IT_fl, sizeof( struct Case_Item_ ), 500, 100 ); } /** diff --git a/src/express/dict.c b/src/express/dict.c index 320a03cf4..69d8d1dd8 100644 --- a/src/express/dict.c +++ b/src/express/dict.c @@ -33,16 +33,12 @@ * Initial revision */ -#include #include "express/dict.h" #include "express/object.h" #include "express/expbasic.h" char DICT_type; /**< set to type of object found, as a side-effect of DICT lookup routines */ -static Error ERROR_duplicate_decl; -static Error ERROR_duplicate_decl_diff_file; - void DICTprint( Dictionary dict ) { Element e; DictionaryEntry de; @@ -58,16 +54,10 @@ void DICTprint( Dictionary dict ) { /** Initialize the Dictionary module */ void DICTinitialize( void ) { - ERROR_duplicate_decl = ERRORcreate( - "Redeclaration of %s. Previous declaration was on line %d.", SEVERITY_ERROR ); - ERROR_duplicate_decl_diff_file = ERRORcreate( - "Redeclaration of %s. Previous declaration was on line %d in file %s.", SEVERITY_ERROR ); } /** Clean up the Dictionary module */ void DICTcleanup( void ) { - ERRORdestroy( ERROR_duplicate_decl ); - ERRORdestroy( ERROR_duplicate_decl_diff_file ); } /** @@ -75,7 +65,7 @@ void DICTcleanup( void ) { * error directly if there is a duplicate value. * \return 0 on success, 1 on failure */ -int DICTdefine( Dictionary dict, char * name, Generic obj, Symbol * sym, char type ) { +int DICTdefine( Dictionary dict, char * name, void *obj, Symbol * sym, char type ) { struct Element_ new, *old; new.key = name; @@ -105,11 +95,11 @@ int DICTdefine( Dictionary dict, char * name, Generic obj, Symbol * sym, char ty /* if we're adding a non-enum, and we've * * already added a non-enum, complain */ if( sym->filename == old->symbol->filename ) { - ERRORreport_with_symbol( ERROR_duplicate_decl, sym, name, old->symbol->line ); + ERRORreport_with_symbol( DUPLICATE_DECL, sym, name, old->symbol->line ); } else { - ERRORreport_with_symbol( ERROR_duplicate_decl_diff_file, sym, name, old->symbol->line, old->symbol->filename ); + ERRORreport_with_symbol( DUPLICATE_DECL_DIFF_FILE, sym, name, old->symbol->line, old->symbol->filename ); } - experrc = ERROR_subordinate_failed; + ERRORreport(SUBORDINATE_FAILED); return( 1 ); } return 0; @@ -123,7 +113,7 @@ int DICTdefine( Dictionary dict, char * name, Generic obj, Symbol * sym, char ty * their unusual behavior with respect to scoping and visibility rules * \sa DICTdefine() */ -int DICT_define( Dictionary dict, char * name, Generic obj, Symbol * sym, char type ) { +int DICT_define( Dictionary dict, char * name, void *obj, Symbol * sym, char type ) { struct Element_ e, *e2; e.key = name; @@ -136,11 +126,11 @@ int DICT_define( Dictionary dict, char * name, Generic obj, Symbol * sym, char t } if( sym->filename == e2->symbol->filename ) { - ERRORreport_with_symbol( ERROR_duplicate_decl, sym, name, e2->symbol->line ); + ERRORreport_with_symbol( DUPLICATE_DECL, sym, name, e2->symbol->line ); } else { - ERRORreport_with_symbol( ERROR_duplicate_decl_diff_file, sym, name, e2->symbol->line, e2->symbol->filename ); + ERRORreport_with_symbol( DUPLICATE_DECL_DIFF_FILE, sym, name, e2->symbol->line, e2->symbol->filename ); } - experrc = ERROR_subordinate_failed; + ERRORreport(SUBORDINATE_FAILED); return( 1 ); } @@ -163,7 +153,7 @@ void DICTundefine( Dictionary dict, char * name ) { ** \param name name to look up ** \return the value found, NULL if not found */ -Generic DICTlookup( Dictionary dictionary, char * name ) { +void *DICTlookup( Dictionary dictionary, char * name ) { struct Element_ e, *ep; if( !dictionary ) { @@ -182,7 +172,7 @@ Generic DICTlookup( Dictionary dictionary, char * name ) { /** like DICTlookup but returns symbol, too * \sa DICTlookup() */ -Generic DICTlookup_symbol( Dictionary dictionary, char * name, Symbol ** sym ) { +void *DICTlookup_symbol( Dictionary dictionary, char * name, Symbol ** sym ) { struct Element_ e, *ep; if( !dictionary ) { @@ -199,7 +189,7 @@ Generic DICTlookup_symbol( Dictionary dictionary, char * name, Symbol ** sym ) { return( NULL ); } -Generic DICTdo( DictionaryEntry * dict_entry ) { +void *DICTdo( DictionaryEntry * dict_entry ) { if( 0 == HASHlist( dict_entry ) ) { return 0; } diff --git a/src/express/dummy.c b/src/express/dummy.c new file mode 100644 index 000000000..6956cac06 --- /dev/null +++ b/src/express/dummy.c @@ -0,0 +1,5 @@ +/* + * CMake dummy - unused + */ + +static int unused_1431423134; diff --git a/src/express/entity.c b/src/express/entity.c index 77dd5ca8c..507b2c23f 100644 --- a/src/express/entity.c +++ b/src/express/entity.c @@ -113,12 +113,10 @@ * */ -#include #include "express/entity.h" #include "express/express.h" #include "express/object.h" -struct freelist_head ENTITY_fl; int ENTITY_MARK = 0; /** returns true if variable is declared (or redeclared) directly by entity */ @@ -146,7 +144,7 @@ static Entity ENTITY_find_inherited_entity( Entity entity, char * name, int down entity->search_id = __SCOPE_search_id; LISTdo( entity->u.entity->supertypes, super, Entity ) - if( streq( super->symbol.name, name ) ) { + if( !strcmp( super->symbol.name, name ) ) { return super; } LISTod @@ -160,7 +158,7 @@ static Entity ENTITY_find_inherited_entity( Entity entity, char * name, int down if( down ) { LISTdo( entity->u.entity->subtypes, sub, Entity ) - if( streq( sub->symbol.name, name ) ) { + if( !strcmp( sub->symbol.name, name ) ) { return sub; } LISTod; @@ -177,7 +175,7 @@ static Entity ENTITY_find_inherited_entity( Entity entity, char * name, int down } struct Scope_ * ENTITYfind_inherited_entity( struct Scope_ *entity, char * name, int down ) { - if( streq( name, entity->symbol.name ) ) { + if( !strcmp( name, entity->symbol.name ) ) { return( entity ); } @@ -248,8 +246,6 @@ Variable ENTITYfind_inherited_attribute( struct Scope_ *entity, char * name, * report errors as appropriate */ Variable ENTITYresolve_attr_ref( Entity e, Symbol * grp_ref, Symbol * attr_ref ) { - extern Error ERROR_unknown_supertype; - extern Error ERROR_unknown_attr_in_entity; Entity ref_entity; Variable attr; struct Symbol_ *where; @@ -258,15 +254,13 @@ Variable ENTITYresolve_attr_ref( Entity e, Symbol * grp_ref, Symbol * attr_ref ) /* use entity provided in group reference */ ref_entity = ENTITYfind_inherited_entity( e, grp_ref->name, 0 ); if( !ref_entity ) { - ERRORreport_with_symbol( ERROR_unknown_supertype, grp_ref, - grp_ref->name, e->symbol.name ); + ERRORreport_with_symbol(UNKNOWN_SUPERTYPE, grp_ref, grp_ref->name, e->symbol.name ); return 0; } attr = ( Variable )DICTlookup( ref_entity->symbol_table, attr_ref->name ); if( !attr ) { - ERRORreport_with_symbol( ERROR_unknown_attr_in_entity, - attr_ref, attr_ref->name, + ERRORreport_with_symbol(UNKNOWN_ATTR_IN_ENTITY, attr_ref, attr_ref->name, ref_entity->symbol.name ); /* resolve_failed(e);*/ } @@ -275,38 +269,17 @@ Variable ENTITYresolve_attr_ref( Entity e, Symbol * grp_ref, Symbol * attr_ref ) where = NULL; attr = ENTITYfind_inherited_attribute( e, attr_ref->name, &where ); if( !attr /* was ref_entity? */ ) { - ERRORreport_with_symbol( ERROR_unknown_attr_in_entity, + ERRORreport_with_symbol(UNKNOWN_ATTR_IN_ENTITY, attr_ref, attr_ref->name, e->symbol.name ); } else if( where != NULL ) { - ERRORreport_with_symbol( ERROR_implicit_downcast, attr_ref, + ERRORreport_with_symbol(IMPLICIT_DOWNCAST, attr_ref, where->name ); } } return attr; } -/** -** low-level function for type Entity -** -** \note The attribute list of a new entity is defined as an -** empty list; all other aspects of the entity are initially -** undefined (i.e., have appropriate NULL values). -*/ -Entity ENTITYcreate( Symbol * sym ) { - Scope s = SCOPEcreate( OBJ_ENTITY ); - - s->u.entity = ENTITY_new(); - s->u.entity->attributes = LISTcreate(); - s->u.entity->inheritance = ENTITY_INHERITANCE_UNINITIALIZED; - - /* it's so useful to have a type hanging around for each entity */ - s->u.entity->type = TYPEcreate_name( sym ); - s->u.entity->type->u.type->body = TYPEBODYcreate( entity_ ); - s->u.entity->type->u.type->body->entity = s; - return( s ); -} - /** * currently, this is only used by USEresolve * low-level function for type Entity @@ -320,9 +293,6 @@ Entity ENTITYcopy( Entity e ) { /** Initialize the Entity module. */ void ENTITYinitialize() { - MEMinitialize( &ENTITY_fl, sizeof( struct Entity_ ), 500, 100 ); - OBJcreate( OBJ_ENTITY, SCOPE_get_symbol, "entity", - OBJ_ENTITY_BITS ); } /** @@ -336,14 +306,14 @@ void ENTITYadd_attribute( Entity entity, Variable attr ) { if( attr->name->type->u.type->body->type != op_ ) { /* simple id */ rc = DICTdefine( entity->symbol_table, attr->name->symbol.name, - ( Generic )attr, &attr->name->symbol, OBJ_VARIABLE ); + attr, &attr->name->symbol, OBJ_VARIABLE ); } else { /* SELF\ENTITY.SIMPLE_ID */ rc = DICTdefine( entity->symbol_table, attr->name->e.op2->symbol.name, - ( Generic )attr, &attr->name->symbol, OBJ_VARIABLE ); + attr, &attr->name->symbol, OBJ_VARIABLE ); } if( rc == 0 ) { - LISTadd_last( entity->u.entity->attributes, ( Generic )attr ); + LISTadd_last( entity->u.entity->attributes, attr ); VARput_offset( attr, entity->u.entity->attribute_count ); entity->u.entity->attribute_count++; } @@ -354,7 +324,7 @@ void ENTITYadd_attribute( Entity entity, Variable attr ) { ** \param instance new instance ** Add an item to the instance list of an entity. */ -void ENTITYadd_instance( Entity entity, Generic instance ) { +void ENTITYadd_instance( Entity entity, void *instance ) { if( entity->u.entity->instances == LIST_NULL ) { entity->u.entity->instances = LISTcreate(); } @@ -401,7 +371,7 @@ static void ENTITY_get_all_attributes( Entity entity, Linked_List result ) { ENTITY_get_all_attributes( super, result ); LISTod; /* Gee, aren't they resolved by this time? */ - LISTdo( entity->u.entity->attributes, attr, Generic ) + LISTdo( entity->u.entity->attributes, attr, void * ) LISTadd_last( result, attr ); LISTod; } @@ -437,7 +407,7 @@ Variable ENTITYget_named_attribute( Entity entity, char * name ) { Variable attribute; LISTdo( entity->u.entity->attributes, attr, Variable ) - if( streq( VARget_simple_name( attr ), name ) ) { + if( !strcmp( VARget_simple_name( attr ), name ) ) { return attr; } LISTod; @@ -495,7 +465,7 @@ int ENTITYget_named_attribute_offset( Entity entity, char * name ) { int value; LISTdo( entity->u.entity->attributes, attr, Variable ) - if( streq( VARget_simple_name( attr ), name ) ) + if( !strcmp( VARget_simple_name( attr ), name ) ) return entity->u.entity->inheritance + VARget_offset( ENTITY_find_inherited_attribute( entity, name, 0, 0 ) ); LISTod; diff --git a/src/express/error.c b/src/express/error.c index abcb8a2b0..9b63825c2 100644 --- a/src/express/error.c +++ b/src/express/error.c @@ -24,7 +24,7 @@ * Revision 1.11 1997/10/22 16:10:26 sauderd * This would #include stdarg.h if __STDC__ was defined otherwise it would * #include vararg.h. I changed it to check the configure generated config file - * named sc_cf.h (if HAVE_CONFIG_H is defined - it's also defined by + * named config.h (if HAVE_CONFIG_H is defined - it's also defined by * configure) to see if HAVE_STDARG_H is defined. If it is it #includes stdarg.h * otherwise it #includes vararg.h. If HAVE_CONFIG_H isn't defined then it works * like it used to. @@ -51,22 +51,104 @@ * prettied up interface to print_objects_when_running */ -#include +#include #include #include #include #include - -#ifdef __STDC__ #include -#else -#include -#endif +#include "express/express.h" #include "express/error.h" #include "express/info.h" #include "express/linklist.h" +static struct Error_ LibErrors[] = { + /* dict.c */ + [DUPLICATE_DECL] = {SEVERITY_ERROR, "Redeclaration of %s. Previous declaration was on line %d.", NULL, false}, + [DUPLICATE_DECL_DIFF_FILE] = {SEVERITY_ERROR, "Redeclaration of %s. Previous declaration was on line %d in file %s.", NULL, false}, + /* error.c */ + [SUBORDINATE_FAILED] = {SEVERITY_ERROR, "A subordinate failed.", NULL, false}, + [SYNTAX_EXPECTING] = {SEVERITY_EXIT, "%s, expecting %s in %s %s", NULL, false}, + /* expr.c */ + [INTEGER_EXPRESSION_EXPECTED] = {SEVERITY_WARNING, "Integer expression expected", NULL, false}, + [INTERNAL_UNRECOGNISED_OP_IN_EXPRESOLVE] = {SEVERITY_ERROR, "Opcode unrecognized while trying to resolve expression", NULL, false}, + [ATTRIBUTE_REF_ON_AGGREGATE] = {SEVERITY_ERROR, "Attribute %s cannot be referenced from an aggregate", NULL, false}, + [ATTRIBUTE_REF_FROM_NON_ENTITY] = {SEVERITY_ERROR, "Attribute %s cannot be referenced from a non-entity", NULL, false}, + [INDEXING_ILLEGAL] = {SEVERITY_ERROR, "Indexing is only permitted on aggregates", NULL, false}, + [WARN_INDEXING_MIXED] = {SEVERITY_WARNING, "non-aggregates) and/or different aggregation types.", "indexing", false}, + [ENUM_NO_SUCH_ITEM] = {SEVERITY_ERROR, "Enumeration type %s does not contain item %s", NULL, false}, + [GROUP_REF_NO_SUCH_ENTITY] = {SEVERITY_ERROR, "Group reference failed to find entity %s", NULL, false}, + [GROUP_REF_UNEXPECTED_TYPE] = {SEVERITY_ERROR, "Group reference of unusual expression %s", NULL, false}, + [IMPLICIT_DOWNCAST] = {SEVERITY_WARNING, "Implicit downcast to %s.", "downcast", false}, + [AMBIG_IMPLICIT_DOWNCAST] = {SEVERITY_WARNING, "Possibly ambiguous implicit downcast (%s?).", "downcast", false}, + /* express.c */ + [BAIL_OUT] = {SEVERITY_DUMP, "Aborting due to internal error(s)", NULL, false}, + [SYNTAX] = {SEVERITY_EXIT, "%s in %s %s", NULL, false}, + [REF_NONEXISTENT] = {SEVERITY_ERROR, "USE/REF of non-existent object (%s in schema %s)", NULL, false}, + [TILDE_EXPANSION_FAILED] = {SEVERITY_ERROR, "Tilde expansion for %s failed in EXPRESS_PATH environment variable", NULL, false}, + [SCHEMA_NOT_IN_OWN_SCHEMA_FILE] = {SEVERITY_ERROR, "Schema %s was not found in its own schema file (%s)", NULL, false}, + [UNLABELLED_PARAM_TYPE] = {SEVERITY_ERROR, "Return type or local variable requires type label in `%s'", NULL, false}, + [FILE_UNREADABLE] = {SEVERITY_ERROR, "Could not read file %s: %s", NULL, false}, + [FILE_UNWRITABLE] = {SEVERITY_ERROR, "Could not write file %s: %s", NULL, false}, + [WARN_UNSUPPORTED_LANG_FEAT] = {SEVERITY_WARNING, "Unsupported language feature (%s) at %s:%d", "unsupported", false}, + [WARN_SMALL_REAL] = {SEVERITY_WARNING, "REALs with extremely small magnitude may be interpreted as zero by other EXPRESS parsers " + "(IEEE 754 float denormals are sometimes rounded to zero) - fabs(%f) <= FLT_MIN.", "limits", false}, + /* lexact.c */ + [INCLUDE_FILE] = {SEVERITY_ERROR, "Could not open include file `%s'.", NULL, false}, + [UNMATCHED_CLOSE_COMMENT] = {SEVERITY_ERROR, "unmatched close comment", NULL, false}, + [UNMATCHED_OPEN_COMMENT] = {SEVERITY_ERROR, "unmatched open comment", NULL, false}, + [UNTERMINATED_STRING] = {SEVERITY_ERROR, "unterminated string literal", NULL, false}, + [ENCODED_STRING_BAD_DIGIT] = {SEVERITY_ERROR, "non-hex digit (%c) in encoded string literal", NULL, false}, + [ENCODED_STRING_BAD_COUNT] = {SEVERITY_ERROR, "number of digits (%d) in encoded string literal is not divisible by 8", NULL, false}, + [BAD_IDENTIFIER] = {SEVERITY_ERROR, "identifier (%s) cannot start with underscore", NULL, false}, + [UNEXPECTED_CHARACTER] = {SEVERITY_ERROR, "character (%c) is not a valid lexical element by itself", NULL, false}, + [NONASCII_CHAR] = {SEVERITY_ERROR, "character (0x%x) is not in the EXPRESS character set", NULL, false}, + /* linklist.c */ + [EMPTY_LIST] = {SEVERITY_ERROR, "Empty list in %s.", NULL, false}, + /* resolve.c */ + [UNDEFINED] = {SEVERITY_ERROR, "Reference to undefined object %s.", NULL, false}, + [UNDEFINED_ATTR] = {SEVERITY_ERROR, "Reference to undefined attribute %s.", NULL, false}, + [UNDEFINED_TYPE] = {SEVERITY_ERROR, "Reference to undefined type %s.", NULL, false}, + [UNDEFINED_SCHEMA] = {SEVERITY_ERROR, "Reference to undefined schema %s.", NULL, false}, + [UNKNOWN_ATTR_IN_ENTITY] = {SEVERITY_ERROR, "Unknown attribute %s in entity %s.", NULL, false}, + [UNKNOWN_SUBTYPE] = {SEVERITY_EXIT, "Unknown subtype %s for entity %s.", "unknown_subtype", false}, + [UNKNOWN_SUPERTYPE] = {SEVERITY_ERROR, "Unknown supertype %s for entity %s.", NULL, false}, + [CIRCULAR_REFERENCE] = {SEVERITY_ERROR, "Circularity: definition of %s references itself.", NULL, false}, + [SUBSUPER_LOOP] = {SEVERITY_ERROR, "Entity %s is a subtype of itself", "circular_subtype", false}, + [SUBSUPER_CONTINUATION] = {SEVERITY_ERROR, " (via supertype entity %s)", NULL, false}, + [SELECT_LOOP] = {SEVERITY_ERROR, "Select type %s selects itself", "circular_select", false}, + [SELECT_CONTINUATION] = {SEVERITY_ERROR, " (via select type %s)", NULL, false}, + [SUPERTYPE_RESOLVE] = {SEVERITY_ERROR, "Supertype %s is not an entity (line %d).", NULL, false}, + [SUBTYPE_RESOLVE] = {SEVERITY_ERROR, "Subtype %s resolves to non-entity %s on line %d.", NULL, false}, + [NOT_A_TYPE] = {SEVERITY_ERROR, "Expected a type (or entity) but %s is %s.", NULL, false}, + [FUNCALL_NOT_A_FUNCTION] = {SEVERITY_ERROR, "Function call of %s which is not a function.", NULL, false}, + [UNDEFINED_FUNC] = {SEVERITY_ERROR, "Function %s undefined.", NULL, false}, + [EXPECTED_PROC] = {SEVERITY_ERROR, "%s is used as a procedure call but is not defined as one (line %d).", NULL, false}, + [NO_SUCH_PROCEDURE] = {SEVERITY_ERROR, "No such procedure as %s.", NULL, false}, + [WRONG_ARG_COUNT] = {SEVERITY_WARNING, "Call to %s uses %d arguments, but expected %d.", NULL, false}, + [QUERY_REQUIRES_AGGREGATE] = {SEVERITY_ERROR, "Query expression source must be an aggregate.", NULL, false}, + [SELF_IS_UNKNOWN] = {SEVERITY_ERROR, "SELF is not within an entity declaration.", NULL, false}, + [INVERSE_BAD_ENTITY] = {SEVERITY_ERROR, "Attribute %s is referenced from non-entity-inheriting type.", NULL, false}, + [INVERSE_BAD_ATTR] = {SEVERITY_ERROR, "Unknown attribute %s in entity %s in inverse.", NULL, false}, + [MISSING_SUPERTYPE] = {SEVERITY_ERROR, "Entity %s missing from supertype list for subtype %s.", NULL, false}, + [TYPE_IS_ENTITY] = {SEVERITY_ERROR, "An entity (%s) is not acceptable as an underlying type.", "entity_as_type", false}, + [AMBIGUOUS_ATTR] = {SEVERITY_WARNING, "Ambiguous attribute reference %s.", NULL, false}, + [AMBIGUOUS_GROUP] = {SEVERITY_WARNING, "Ambiguous group reference %s.", NULL, false}, + [OVERLOADED_ATTR] = {SEVERITY_ERROR, "Attribute %s already inherited via supertype %s.", NULL, false}, + [REDECL_NO_SUCH_ATTR] = {SEVERITY_ERROR, "Redeclared attribute %s not declared in supertype %s.", NULL, false}, + [REDECL_NO_SUCH_SUPERTYPE] = {SEVERITY_ERROR, "No such supertype %s for redeclaration of attribute %s.", NULL, false}, + [MISSING_SELF] = {SEVERITY_ERROR, "Domain rule %s must refer to SELF or attribute.", NULL, false}, + [FN_SKIP_BRANCH] = {SEVERITY_WARNING, "IF statement condition is always %s. Ignoring branch that is never taken.", "invariant_condition", false}, + [CASE_SKIP_LABEL] = {SEVERITY_WARNING, "CASE label %s cannot be matched. Ignoring its statements.", "invalid_case", false}, + [UNIQUE_QUAL_REDECL] = {SEVERITY_WARNING, "Possibly unnecessary qualifiers on redeclared attr '%s' in a uniqueness rule of entity '%s'.", "unnecessary_qualifiers", false}, + /* type.c */ + [CORRUPTED_TYPE] = {SEVERITY_DUMP, "Corrupted type in %s", NULL, false}, + [UNDEFINED_TAG] = {SEVERITY_ERROR, "Undefined type tag %s", NULL, false}, + /* exppp.c */ + [SELECT_EMPTY] = {SEVERITY_ERROR, "select type %s has no members", NULL, false}, +}; + bool __ERROR_buffer_errors = false; const char * current_filename = "stdin"; @@ -74,7 +156,6 @@ const char * current_filename = "stdin"; /* flag to remember whether non-warning errors have occurred */ bool ERRORoccurred = false; - Error experrc = ERROR_none; Error ERROR_subordinate_failed = ERROR_none; Error ERROR_syntax_expecting = ERROR_none; @@ -87,13 +168,8 @@ int malloc_debug_resolve = 0; /* for debugging yacc/lex */ int debug = 0; -struct Linked_List_ * ERRORwarnings; -struct freelist_head ERROR_OPT_fl; - void ( *ERRORusage_function )( void ); -#include "express/express.h" - #define ERROR_MAX_ERRORS 100 /**< max line-numbered errors */ #define ERROR_MAX_SPACE 4000 /**< max space for line-numbered errors */ #define ERROR_MAX_STRLEN 200 /**< assuming all error messages are less than this, @@ -112,6 +188,7 @@ static struct heap_element { static int ERROR_with_lines = 0; /**< number of warnings & errors that have occurred with a line number */ static char * ERROR_string; static char * ERROR_string_base; +static char * ERROR_string_end; static bool ERROR_unsafe = false; static jmp_buf ERROR_safe_env; @@ -119,17 +196,41 @@ static jmp_buf ERROR_safe_env; #define error_file stderr /**< message buffer file */ +static int ERROR_vprintf( const char *format, va_list ap ) { + int result = vsnprintf( ERROR_string, ERROR_string_end - ERROR_string, format, ap ); + + if(result < 0) { + ERROR_string = ERROR_string_end; + } else if(result > (ERROR_string_end - ERROR_string)) { + ERROR_string = ERROR_string_end; + } else { + ERROR_string = ERROR_string + result; + } + return result; +} + +static int ERROR_printf( const char *format, ... ) { + int result; + va_list ap; + va_start( ap, format ); + result = ERROR_vprintf( format, ap ); + va_end( ap ); + return result; +} + +static void ERROR_nexterror() { + if( ERROR_string == ERROR_string_end ) { + return; + } + ERROR_string++; +} + /** Initialize the Error module */ void ERRORinitialize( void ) { - ERROR_subordinate_failed = - ERRORcreate( "A subordinate failed.", SEVERITY_ERROR ); - ERROR_syntax_expecting = - ERRORcreate( "%s, expecting %s in %s %s", SEVERITY_EXIT ); - - ERROR_string_base = ( char * )sc_malloc( ERROR_MAX_SPACE ); + ERROR_string_base = ( char * )malloc( ERROR_MAX_SPACE ); + ERROR_string_end = ERROR_string_base + ERROR_MAX_SPACE; ERROR_start_message_buffer(); - #ifdef SIGQUIT signal( SIGQUIT, ERRORabort ); #endif @@ -146,58 +247,22 @@ void ERRORinitialize( void ) { /** Clean up the Error module */ void ERRORcleanup( void ) { - ERRORdestroy( ERROR_subordinate_failed ); - ERRORdestroy( ERROR_syntax_expecting ); - - sc_free( ERROR_string_base ); + free( ERROR_string_base ); } -/** Need the LIST routines to complete ERROR initialization */ -void ERRORinitialize_after_LIST( void ) { - ERRORwarnings = LISTcreate(); - - MEMinitialize( &ERROR_OPT_fl, sizeof( struct Error_Warning_ ), 5, 5 ); -} - -void ERRORcreate_warning( char * name, Error error ) { - struct Error_Warning_ *o; - - /* first check if we know about this type of error */ - LISTdo( ERRORwarnings, opt, Error_Warning ) { - if( streq( name, opt->name ) ) { - LISTadd_last( opt->errors, ( Generic )error ); - return; +void ERRORset_warning(char * name, bool warn_only) { + Error err; + bool found = false; + + for (unsigned int errnum = 0; errnum < (sizeof LibErrors / sizeof LibErrors[0]); errnum++) { + err = &LibErrors[errnum]; + if (err->severity <= SEVERITY_WARNING && !strcmp(err->name, name)) { + found = true; + err->override = warn_only; } - } LISTod - - /* new error */ - o = ERROR_OPT_new(); - o->name = name; - o->errors = LISTcreate(); - LISTadd_last( o->errors, ( Generic )error ); - LISTadd_last( ERRORwarnings, ( Generic )o ); -} - -void ERRORset_warning( char * name, int set ) { - - if( streq( name, "all" ) ) { - ERRORset_all_warnings( set ); - } else if( streq( name, "none" ) ) { - ERRORset_all_warnings( !set ); - } else { - bool found = false; - LISTdo( ERRORwarnings, opt, Error_Warning ) { - if( streq( opt->name, name ) ) { - found = true; - LISTdo_n( opt->errors, err, Error, b ) { - err->enabled = set; - } LISTod - } - } LISTod - if( found ) { - return; - } - + } + + if (!found) { fprintf( stderr, "unknown warning: %s\n", name ); if( ERRORusage_function ) { ( *ERRORusage_function )(); @@ -207,24 +272,56 @@ void ERRORset_warning( char * name, int set ) { } } -/** \fn ERRORdisable -** \param error error to disable -** Disable an error (ERRORreport*() will ignore it) -** \note this function is inlined in error.h -*/ +void ERRORset_all_warnings( bool warn_only ) { + Error err; + + for (unsigned int errnum = 0; errnum < (sizeof LibErrors / sizeof LibErrors[0]); errnum++) { + err = &LibErrors[errnum]; + if (err->severity <= SEVERITY_WARNING) { + err->override = warn_only; + } + } +} -/** \fn ERRORenable -** \param error error to enable -** Enable an error (ERRORreport*() will report it) -** \note this function is inlined in error.h -*/ +char * ERRORget_warnings_help(const char* prefix, const char *eol) { + unsigned int sz = 2048, len, clen; + char *buf, *nbuf; + Error err; + + clen = strlen(prefix) + strlen(eol) + 1; + + buf = malloc(sz); + if (!buf) { + fprintf(error_file, "failed to allocate memory for warnings help!\n"); + } + buf[0] = '\0'; + + for (unsigned int errnum = 0; errnum < (sizeof LibErrors / sizeof LibErrors[0]); errnum++) { + err = &LibErrors[errnum]; + if (err->name) { + len = strlen(buf) + strlen(err->name) + clen; + if (len > sz) { + sz *= 2; + nbuf = realloc(buf, sz); + if (!nbuf) { + fprintf(error_file, "failed to reallocate / grow memory for warnings help!\n"); + } + buf = nbuf; + } + strcat(buf, prefix); + strcat(buf, err->name); + strcat(buf, eol); + } + } + + return buf; +} -/** \fn ERRORis_enabled -** \param error error to test -** \return is reporting of the error enabled? -** Check whether an error is enabled -** \note this function is inlined in error.h -*/ +bool +ERRORis_enabled(enum ErrorCode errnum) { + Error err = &LibErrors[errnum]; + return !err->override; +} /** \fn ERRORreport ** \param what error to report @@ -234,42 +331,21 @@ void ERRORset_warning( char * name, int set ) { ** Notes: The second and subsequent arguments should match the ** format fields of the message generated by 'what.' */ -void ERRORset_all_warnings( int set ) { - LISTdo( ERRORwarnings, opts, Error_Warning ) { - LISTdo_n( opts->errors, err, Error, b ) { - err->enabled = set; - } LISTod - } LISTod -} - void -#ifdef __STDC__ -ERRORreport( Error what, ... ) { -#else -ERRORreport( va_alist ) -va_dcl { - Error what; -#endif - /* extern void abort(void);*/ +ERRORreport( enum ErrorCode errnum, ... ) { va_list args; -#ifdef __STDC__ - va_start( args, what ); -#else - va_start( args ); - what = va_arg( args, Error ); -#endif + va_start( args, errnum ); + Error what = &LibErrors[errnum]; - if( ( what != ERROR_none ) && - ( what != ERROR_subordinate_failed ) && - what->enabled ) { + if (errnum != SUBORDINATE_FAILED && ERRORis_enabled(errnum) ) { if( what->severity >= SEVERITY_ERROR ) { - fprintf( error_file, "ERROR PE%03d: ", what->serial ); + fprintf( error_file, "ERROR PE%03d: ", errnum ); vfprintf( error_file, what->message, args ); fputc( '\n', error_file ); ERRORoccurred = true; } else { - fprintf( error_file, "WARNING PW%03d: %d", what->serial, what->severity ); + fprintf( error_file, "WARNING PW%03d: %d", errnum, what->severity ); vfprintf( error_file, what->message, args ); fputc( '\n', error_file ); } @@ -282,7 +358,6 @@ va_dcl { } } } - experrc = ERROR_none; va_end( args ); } @@ -296,62 +371,23 @@ va_dcl { ** format fields of the message generated by 'what.' */ void -#ifdef __STDC__ -ERRORreport_with_line( Error what, int line, ... ) { -#else -ERRORreport_with_line( va_alist ) -va_dcl { - Error what; - int line; -#endif - - char buf[BUFSIZ]; - char * savemsg; /* save what->message here while we fool */ - /* ERRORreport_with_line */ +ERRORreport_with_line( enum ErrorCode errnum, int line, ... ) { Symbol sym; va_list args; -#ifdef __STDC__ va_start( args, line ); -#else - va_start( args ); - what = va_arg( args, Error ); - line = va_arg( args, int ); -#endif sym.filename = current_filename; sym.line = line; - - vsprintf( buf, what->message, args ); - - /* gross, but there isn't any way to do this more directly */ - /* without writing yet another variant of ERRORreport_with_line */ - savemsg = what->message; - what->message = "%s"; - ERRORreport_with_symbol( what, &sym, buf ); - what->message = savemsg; + ERRORreport_with_symbol(errnum, &sym, args); } void -#ifdef __STDC__ -ERRORreport_with_symbol( Error what, Symbol * sym, ... ) { -#else -ERRORreport_with_symbol( va_alist ) -va_dcl { - Error what; - Symbol * sym; -#endif - /* extern void abort(void);*/ +ERRORreport_with_symbol( enum ErrorCode errnum, Symbol * sym, ... ) { va_list args; - -#ifdef __STDC__ va_start( args, sym ); -#else - va_start( args ); - what = va_arg( args, Error ); - sym = va_arg( args, Symbol * ); -#endif + Error what = &LibErrors[errnum]; - if( ( what != ERROR_none ) && ( what != ERROR_subordinate_failed ) && what->enabled ) { + if (errnum != SUBORDINATE_FAILED && ERRORis_enabled(errnum)) { if( __ERROR_buffer_errors ) { int child, parent; @@ -377,20 +413,14 @@ va_dcl { heap[child].msg = ERROR_string; if( what->severity >= SEVERITY_ERROR ) { - sprintf( ERROR_string, "%s:%d: --ERROR PE%03d: ", sym->filename, sym->line, what->serial ); - ERROR_string += strlen( ERROR_string ); - vsprintf( ERROR_string, what->message, args ); - ERROR_string += strlen( ERROR_string ); - *ERROR_string++ = '\n'; - *ERROR_string++ = '\0'; + ERROR_printf( "%s:%d: --ERROR PE%03d: ", sym->filename, sym->line, errnum ); + ERROR_vprintf( what->message, args ); + ERROR_nexterror(); ERRORoccurred = true; } else { - sprintf( ERROR_string, "%s:%d: WARNING PW%03d: ", sym->filename, sym->line, what->serial ); - ERROR_string += strlen( ERROR_string ); - vsprintf( ERROR_string, what->message, args ); - ERROR_string += strlen( ERROR_string ); - *ERROR_string++ = '\n'; - *ERROR_string++ = '\0'; + ERROR_printf( "%s:%d: WARNING PW%03d: ", sym->filename, sym->line, errnum ); + ERROR_vprintf( what->message, args ); + ERROR_nexterror(); } if( what->severity >= SEVERITY_EXIT || ERROR_string + ERROR_MAX_STRLEN > ERROR_string_base + ERROR_MAX_SPACE || @@ -404,13 +434,12 @@ va_dcl { } } else { if( what->severity >= SEVERITY_ERROR ) { - fprintf( error_file, "%s:%d: --ERROR PE%03d: ", sym->filename, sym->line, what->serial ); + fprintf( error_file, "%s:%d: --ERROR PE%03d: ", sym->filename, sym->line, errnum ); vfprintf( error_file, what->message, args ); fprintf( error_file, "\n" ); ERRORoccurred = true; } else { - fprintf( error_file, "%s:%d: WARNING PW%03d: ", sym->filename, sym->line, what->serial ); - ERROR_string += strlen( ERROR_string ) + 1; + fprintf( error_file, "%s:%d: WARNING PW%03d: ", sym->filename, sym->line, errnum ); vfprintf( error_file, what->message, args ); fprintf( error_file, "\n" ); } @@ -423,7 +452,6 @@ va_dcl { } } } - experrc = ERROR_none; va_end( args ); } @@ -432,28 +460,6 @@ void ERRORnospace() { ERRORabort( 0 ); } -/** -** \param message error message -** \param severity severity of error -** \return newly created error -** Create a new error -*/ -Error ERRORcreate( char * message, Severity severity ) { - static int errnum = 0; /* give each error type a unique identifier */ - Error n; - - n = ( struct Error_ * )sc_malloc( sizeof( struct Error_ ) ); - n->message = message; - n->severity = severity; - n->enabled = true; - n->serial = errnum++; - return n; -} - -void ERRORdestroy( Error error ) { - sc_free( error ); -} - /** \fn ERRORbuffer_messages ** \param flag - to buffer or not to buffer ** Selects buffering of error messages @@ -473,7 +479,7 @@ void ERROR_start_message_buffer( void ) { } void ERROR_flush_message_buffer( void ) { - if( __ERROR_buffer_errors == false ) { + if(!__ERROR_buffer_errors) { return; } @@ -509,16 +515,21 @@ void ERROR_flush_message_buffer( void ) { void ERRORabort( int sig ) { (void) sig; /* quell unused param warning */ - ERRORflush_messages(); - if( !ERRORdebugging ) { - if( ERROR_unsafe ) { - longjmp( ERROR_safe_env, 1 ); - } + + /* TODO: rework - fprintf is not atomic + * so ERRORflush_messages() is unsafe if __ERROR_buffer_errors is set + */ + + /* NOTE: signals can be caught in gdb, + * no need for special treatment of debugging scenario */ + if( ERROR_unsafe ) { + longjmp( ERROR_safe_env, 1 ); + } #ifdef SIGABRT - signal( SIGABRT, SIG_DFL ); + signal( SIGABRT, SIG_DFL ); #endif - abort(); - } + /* TODO: library shouldn't abort an application? */ + abort(); } void ERRORsafe( jmp_buf env ) { diff --git a/src/express/expparse.y b/src/express/expparse.y index 1817c2e7c..92a9bfcca 100644 --- a/src/express/expparse.y +++ b/src/express/expparse.y @@ -51,7 +51,7 @@ YYSTYPE yylval; Express yyexpresult; /* hook to everything built by parser */ Symbol *interface_schema; /* schema of interest in use/ref clauses */ - void (*interface_func)(); /* func to attach rename clauses */ + void (*interface_func)(struct Scope_ *, Symbol *, Symbol *, Symbol *); /* func to attach rename clauses */ /* record schemas found in a single parse here, allowing them to be */ /* differentiated from other schemas parsed earlier */ @@ -106,7 +106,7 @@ YYSTYPE yylval; #define ERROR(code) ERRORreport(code, yylineno) -void parserInitState() +void parserInitState( void ) { scope = scopes; /* no need to define scope->this */ @@ -402,8 +402,7 @@ aggregate_type(A) ::= TOK_AGGREGATE TOK_OF parameter_type(B). Symbol sym; sym.line = yylineno; sym.filename = current_filename; - ERRORreport_with_symbol(ERROR_unlabelled_param_type, &sym, - CURRENT_SCOPE_NAME); + ERRORreport_with_symbol(UNLABELLED_PARAM_TYPE, &sym, CURRENT_SCOPE_NAME); } } aggregate_type(A) ::= TOK_AGGREGATE TOK_COLON TOK_IDENTIFIER(B) TOK_OF @@ -1257,7 +1256,7 @@ generic_type(A) ::= TOK_GENERIC. Symbol sym; sym.line = yylineno; sym.filename = current_filename; - ERRORreport_with_symbol(ERROR_unlabelled_param_type, &sym, + ERRORreport_with_symbol(UNLABELLED_PARAM_TYPE, &sym, CURRENT_SCOPE_NAME); } } @@ -1340,11 +1339,11 @@ initializer(A) ::= TOK_ASSIGNMENT expression(B). */ rename ::= TOK_IDENTIFIER(A). { - (*interface_func)(CURRENT_SCOPE, interface_schema, A, A); + (*interface_func)(CURRENT_SCOPE, interface_schema, A.symbol, A.symbol); } rename ::= TOK_IDENTIFIER(A) TOK_AS TOK_IDENTIFIER(B). { - (*interface_func)(CURRENT_SCOPE, interface_schema, A, B); + (*interface_func)(CURRENT_SCOPE, interface_schema, A.symbol, B.symbol); } rename_list(A) ::= rename(B). @@ -1551,7 +1550,7 @@ literal(A) ::= TOK_REAL_LITERAL(B). Symbol sym; sym.line = yylineno; sym.filename = current_filename; - ERRORreport_with_symbol(ERROR_warn_small_real, &sym, B.rVal ); + ERRORreport_with_symbol(WARN_SMALL_REAL, &sym, B.rVal ); } if( fabs( B.rVal ) < DBL_MIN ) { A = LITERAL_ZERO; @@ -2431,7 +2430,7 @@ while_control(A) ::= TOK_WHILE expression(B). sym.line = yylineno; sym.filename = current_filename; - ERRORreport_with_symbol(ERROR_syntax, &sym, "Syntax error", + ERRORreport_with_symbol(SYNTAX, &sym, "Syntax error", CURRENT_SCOPE_TYPE_PRINTABLE, CURRENT_SCOPE_NAME); } @@ -2439,5 +2438,8 @@ while_control(A) ::= TOK_WHILE expression(B). %stack_overflow { fprintf(stderr, "Express parser experienced stack overflow.\n"); - fprintf(stderr, "Last token had value %x\n", yypMinor->yy0.val); + /* + * fprintf(stderr, "Last token had value %x\n", yypMinor->yy0.val); + * fprintf(stderr, "Last token had value %x\n", yypParser->yytos->minor.yy0.val); + */ } diff --git a/src/express/expr.c b/src/express/expr.c index 72a69586b..19ab0af91 100644 --- a/src/express/expr.c +++ b/src/express/expr.c @@ -70,12 +70,12 @@ * */ -#include +#include +#include + #include "express/expr.h" #include "express/resolve.h" -#include -#include struct EXPop_entry EXPop_table[OP_LAST]; @@ -85,28 +85,9 @@ Expression LITERAL_PI = EXPRESSION_NULL; Expression LITERAL_ZERO = EXPRESSION_NULL; Expression LITERAL_ONE; -Error ERROR_bad_qualification = ERROR_none; -Error ERROR_integer_expression_expected = ERROR_none; -Error ERROR_implicit_downcast = ERROR_none; -Error ERROR_ambig_implicit_downcast = ERROR_none; - -struct freelist_head EXP_fl; -struct freelist_head OP_fl; -struct freelist_head QUERY_fl; -struct freelist_head QUAL_ATTR_fl; - void EXPop_init(); -static Error ERROR_internal_unrecognized_op_in_EXPresolve; -/* following two could probably be combined */ -static Error ERROR_attribute_reference_on_aggregate; -static Error ERROR_attribute_ref_from_nonentity; -static Error ERROR_indexing_illegal; -static Error ERROR_warn_indexing_mixed; -static Error ERROR_enum_no_such_item; -static Error ERROR_group_ref_no_such_entity; -static Error ERROR_group_ref_unexpected_type; - -static_inline int OPget_number_of_operands( Op_Code op ) { + +static inline int OPget_number_of_operands( Op_Code op ) { if( ( op == OP_NEGATE ) || ( op == OP_NOT ) ) { return 1; } else if( op == OP_SUBCOMPONENT ) { @@ -116,49 +97,8 @@ static_inline int OPget_number_of_operands( Op_Code op ) { } } -Expression EXPcreate( Type type ) { - Expression e; - e = EXP_new(); - SYMBOLset( e ); - e->type = type; - e->return_type = Type_Unknown; - return( e ); -} - -/** - * use this when the return_type is the same as the type - * For example, for constant integers - */ -Expression EXPcreate_simple( Type type ) { - Expression e; - e = EXP_new(); - SYMBOLset( e ); - e->type = e->return_type = type; - return( e ); -} - -Expression EXPcreate_from_symbol( Type type, Symbol * symbol ) { - Expression e; - e = EXP_new(); - e->type = type; - e->return_type = Type_Unknown; - e->symbol = *symbol; - return e; -} - -Symbol * EXP_get_symbol( Generic e ) { - return( &( ( Expression )e )->symbol ); -} - /** Description: Initialize the Expression module. */ void EXPinitialize( void ) { - MEMinitialize( &EXP_fl, sizeof( struct Expression_ ), 500, 200 ); - MEMinitialize( &OP_fl, sizeof( struct Op_Subexpression ), 500, 100 ); - MEMinitialize( &QUERY_fl, sizeof( struct Query_ ), 50, 10 ); - MEMinitialize( &QUAL_ATTR_fl, sizeof( struct Query_ ), 20, 10 ); - OBJcreate( OBJ_EXPRESSION, EXP_get_symbol, "expression", OBJ_EXPRESSION_BITS ); - OBJcreate( OBJ_AMBIG_ENUM, EXP_get_symbol, "ambiguous enumeration", OBJ_UNUSED_BITS ); - #ifdef does_not_appear_to_be_necessary_or_even_make_sense LITERAL_EMPTY_SET = EXPcreate_simple( Type_Set ); LITERAL_EMPTY_SET->u.list = LISTcreate(); @@ -193,58 +133,10 @@ void EXPinitialize( void ) { LITERAL_ONE->u.integer = 1; resolved_all( LITERAL_ONE ); - ERROR_integer_expression_expected = ERRORcreate( - "Integer expression expected", SEVERITY_WARNING ); - - ERROR_internal_unrecognized_op_in_EXPresolve = ERRORcreate( - "Opcode unrecognized while trying to resolve expression", SEVERITY_ERROR ); - - ERROR_attribute_reference_on_aggregate = ERRORcreate( - "Attribute %s cannot be referenced from an aggregate", SEVERITY_ERROR ); - - ERROR_attribute_ref_from_nonentity = ERRORcreate( - "Attribute %s cannot be referenced from a non-entity", SEVERITY_ERROR ); - - ERROR_indexing_illegal = ERRORcreate( - "Indexing is only permitted on aggregates", SEVERITY_ERROR ); - - ERROR_warn_indexing_mixed = ERRORcreate( "Indexing upon a select (%s), with mixed base types (aggregates and " - "non-aggregates) and/or different aggregation types.", SEVERITY_WARNING ); - - ERROR_enum_no_such_item = ERRORcreate( - "Enumeration type %s does not contain item %s", SEVERITY_ERROR ); - - ERROR_group_ref_no_such_entity = ERRORcreate( - "Group reference failed to find entity %s", SEVERITY_ERROR ); - - ERROR_group_ref_unexpected_type = ERRORcreate( - "Group reference of unusual expression %s", SEVERITY_ERROR ); - - ERROR_implicit_downcast = ERRORcreate( - "Implicit downcast to %s.", SEVERITY_WARNING ); - - ERROR_ambig_implicit_downcast = ERRORcreate( - "Possibly ambiguous implicit downcast (%s?).", SEVERITY_WARNING ); - - ERRORcreate_warning( "downcast", ERROR_implicit_downcast ); - ERRORcreate_warning( "downcast", ERROR_ambig_implicit_downcast ); - ERRORcreate_warning( "indexing", ERROR_warn_indexing_mixed ); - EXPop_init(); } void EXPcleanup( void ) { - ERRORdestroy( ERROR_integer_expression_expected ); - ERRORdestroy( ERROR_internal_unrecognized_op_in_EXPresolve ); - ERRORdestroy( ERROR_attribute_reference_on_aggregate ); - ERRORdestroy( ERROR_attribute_ref_from_nonentity ); - ERRORdestroy( ERROR_indexing_illegal ); - ERRORdestroy( ERROR_warn_indexing_mixed ); - ERRORdestroy( ERROR_enum_no_such_item ); - ERRORdestroy( ERROR_group_ref_no_such_entity ); - ERRORdestroy( ERROR_group_ref_unexpected_type ); - ERRORdestroy( ERROR_implicit_downcast ); - ERRORdestroy( ERROR_ambig_implicit_downcast ); } /** @@ -297,9 +189,9 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol sref, Expression * e * sure of the circumstances in which this is beneficial. */ *where = w; - LISTadd_last( subt, (Generic) w ); + LISTadd_last( subt, w ); } else { - LISTadd_last( supert, (Generic) t ); + LISTadd_last( supert, t ); } options += nr; } @@ -316,7 +208,7 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol sref, Expression * e } } LISTod if( !found ) { - LISTadd_last( uniqSubs, (Generic) s ); + LISTadd_last( uniqSubs, s ); } } LISTod if( ( LISTget_length( uniqSubs ) == 0 ) && ( LISTget_length( supert ) == 1 ) && ( options > 1 ) ) { @@ -339,6 +231,8 @@ static int EXP_resolve_op_dot_fuzzy( Type selection, Symbol sref, Expression * e *e = item; *dt = DICT_type; return 1; + } else { + return 0; } default: return 0; @@ -395,10 +289,10 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) { LISTod; if( all_enums ) { - ERRORreport_with_symbol( WARNING_case_skip_label, &op2->symbol, op2->symbol.name ); + ERRORreport_with_symbol(CASE_SKIP_LABEL, &op2->symbol, op2->symbol.name ); } else { /* no possible resolutions */ - ERRORreport_with_symbol( ERROR_undefined_attribute, &op2->symbol, op2->symbol.name ); + ERRORreport_with_symbol(UNDEFINED_ATTR, &op2->symbol, op2->symbol.name ); } resolve_failed( expr ); return( Type_Bad ); @@ -406,7 +300,7 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) { /* only one possible resolution */ if( dt == OBJ_VARIABLE ) { if( where ) { - ERRORreport_with_symbol( ERROR_implicit_downcast, &op2->symbol, where->name ); + ERRORreport_with_symbol(IMPLICIT_DOWNCAST, &op2->symbol, where->name ); } if( v == VARIABLE_NULL ) { @@ -425,13 +319,14 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) { } else { fprintf( stderr, "EXPresolved_op_dot: attribute not an attribute?\n" ); ERRORabort( 0 ); + return( Type_Bad ); } default: /* compile-time ambiguous */ if( where ) { /* this is actually a warning, not an error */ - ERRORreport_with_symbol( ERROR_ambig_implicit_downcast, &op2->symbol, where->name ); + ERRORreport_with_symbol(AMBIG_IMPLICIT_DOWNCAST, &op2->symbol, where->name ); } return( Type_Runtime ); } @@ -479,7 +374,7 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) { * which calls EXP_resolve_op_dot_fuzzy(). */ item = ( Expression )DICTlookup( TYPEget_enum_tags( op1type ), op2->symbol.name ); if( !item ) { - ERRORreport_with_symbol( ERROR_enum_no_such_item, &op2->symbol, + ERRORreport_with_symbol(ENUM_NO_SUCH_ITEM, &op2->symbol, op1type->symbol.name, op2->symbol.name ); resolve_failed( expr ); return( Type_Bad ); @@ -494,7 +389,7 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) { case bag_: case list_: case set_: - ERRORreport_with_symbol( ERROR_attribute_reference_on_aggregate, + ERRORreport_with_symbol(ATTRIBUTE_REF_ON_AGGREGATE, &op2->symbol, op2->symbol.name ); /*FALLTHRU*/ case unknown_: /* unable to resolved operand */ @@ -502,7 +397,7 @@ Type EXPresolve_op_dot( Expression expr, Scope scope ) { resolve_failed( expr ); return( Type_Bad ); default: - ERRORreport_with_symbol( ERROR_attribute_ref_from_nonentity, + ERRORreport_with_symbol(ATTRIBUTE_REF_FROM_NON_ENTITY, &op2->symbol, op2->symbol.name ); resolve_failed( expr ); return( Type_Bad ); @@ -599,7 +494,7 @@ Type EXPresolve_op_group( Expression expr, Scope scope ) { ent_ref = ( Entity )ENTITYfind_inherited_entity( tmp, op2->symbol.name, 1 ); if( !ent_ref ) { - ERRORreport_with_symbol( ERROR_group_ref_no_such_entity, + ERRORreport_with_symbol(GROUP_REF_NO_SUCH_ENTITY, &op2->symbol, op2->symbol.name ); resolve_failed( expr ); return( Type_Bad ); @@ -627,7 +522,7 @@ Type EXPresolve_op_group( Expression expr, Scope scope ) { switch( options ) { case 0: /* no possible resolutions */ - ERRORreport_with_symbol( ERROR_group_ref_no_such_entity, + ERRORreport_with_symbol(GROUP_REF_NO_SUCH_ENTITY, &op2->symbol, op2->symbol.name ); resolve_failed( expr ); return( Type_Bad ); @@ -657,7 +552,7 @@ Type EXPresolve_op_group( Expression expr, Scope scope ) { case list_: case set_: default: - ERRORreport_with_symbol( ERROR_group_ref_unexpected_type, + ERRORreport_with_symbol(GROUP_REF_UNEXPECTED_TYPE, &op1->symbol ); return( Type_Bad ); } @@ -709,13 +604,13 @@ Type EXPresolve_op_relational( Expression e, Scope s ) { void EXPresolve_op_default( Expression e, Scope s ) { int failed = 0; - switch( OPget_number_of_operands( e->e.op_code ) ) { - case 3: - EXPresolve( e->e.op3, s, Type_Dont_Care ); - failed = is_resolve_failed( e->e.op3 ); - case 2: - EXPresolve( e->e.op2, s, Type_Dont_Care ); - failed |= is_resolve_failed( e->e.op2 ); + if( OPget_number_of_operands( e->e.op_code ) == 3 ) { + EXPresolve( e->e.op3, s, Type_Dont_Care ); + failed = is_resolve_failed( e->e.op3 ); + } + if( OPget_number_of_operands( e->e.op_code ) == 2 ) { + EXPresolve( e->e.op2, s, Type_Dont_Care ); + failed |= is_resolve_failed( e->e.op2 ); } EXPresolve( e->e.op1, s, Type_Dont_Care ); if( failed || is_resolve_failed( e->e.op1 ) ) { @@ -729,11 +624,11 @@ void EXPresolve_op_default( Expression e, Scope s ) { Type EXPresolve_op_unknown( Expression e, Scope s ) { (void) e; /* quell unused param warning */ (void) s; - ERRORreport( ERROR_internal_unrecognized_op_in_EXPresolve ); + ERRORreport( INTERNAL_UNRECOGNISED_OP_IN_EXPRESOLVE ); return Type_Bad; } -typedef Type Resolve_expr_func PROTO( ( Expression , Scope ) ); +typedef Type (Resolve_expr_func) ( Expression , Scope ); Type EXPresolve_op_logical( Expression e, Scope s ) { EXPresolve_op_default( e, s ); @@ -752,7 +647,7 @@ Type EXPresolve_op_array_like( Expression e, Scope s ) { } else if( op1type == Type_Runtime ) { return( Type_Runtime ); } else if( op1type->u.type->body->type == binary_ ) { - ERRORreport_with_symbol( ERROR_warn_unsupported_lang_feat, &e->symbol, "indexing on a BINARY", __FILE__, __LINE__ ); + ERRORreport_with_symbol(WARN_UNSUPPORTED_LANG_FEAT, &e->symbol, "indexing on a BINARY", __FILE__, __LINE__ ); return( Type_Binary ); } else if( op1type->u.type->body->type == generic_ ) { return( Type_Generic ); @@ -794,15 +689,15 @@ Type EXPresolve_op_array_like( Expression e, Scope s ) { return( lasttype->u.type->body->base ); } else if( numNonAggr == 0 ) { /* All aggregates, but different types */ - ERRORreport_with_symbol( ERROR_warn_indexing_mixed, &e->symbol, op1type->symbol.name ); + ERRORreport_with_symbol(WARN_INDEXING_MIXED, &e->symbol, op1type->symbol.name ); return( lasttype->u.type->body->base ); /* WARNING I'm assuming that any of the types is acceptable!!! */ } else if( numAggr != 0 ) { /* One or more aggregates, one or more nonaggregates */ - ERRORreport_with_symbol( ERROR_warn_indexing_mixed, &e->symbol, op1type->symbol.name ); + ERRORreport_with_symbol(WARN_INDEXING_MIXED, &e->symbol, op1type->symbol.name ); return( lasttype->u.type->body->base ); /* WARNING I'm assuming that any of the types is acceptable!!! */ } /* Else, all are nonaggregates. This is an error. */ } - ERRORreport_with_symbol( ERROR_indexing_illegal, &e->symbol ); + ERRORreport_with_symbol(INDEXING_ILLEGAL, &e->symbol ); return( Type_Unknown ); } @@ -897,78 +792,6 @@ void EXPop_init() { EXPop_create( OP_UNKNOWN, "UNKNOWN OP", EXPresolve_op_unknown ); } - -/** -** \param op operation -** \param operand1 - first operand -** \param operand2 - second operand -** \param operand3 - third operand -** \returns Ternary_Expression - the expression created -** Create a ternary operation Expression. -*/ -Expression TERN_EXPcreate( Op_Code op, Expression operand1, Expression operand2, Expression operand3 ) { - Expression e = EXPcreate( Type_Expression ); - - e->e.op_code = op; - e->e.op1 = operand1; - e->e.op2 = operand2; - e->e.op3 = operand3; - return e; -} - -/** -** \fn BIN_EXPcreate -** \param op operation -** \param operand1 - first operand -** \param operand2 - second operand -** \returns Binary_Expression - the expression created -** Create a binary operation Expression. -*/ -Expression BIN_EXPcreate( Op_Code op, Expression operand1, Expression operand2 ) { - Expression e = EXPcreate( Type_Expression ); - - e->e.op_code = op; - e->e.op1 = operand1; - e->e.op2 = operand2; - return e; -} - -/** -** \param op operation -** \param operand operand -** \returns the expression created -** Create a unary operation Expression. -*/ -Expression UN_EXPcreate( Op_Code op, Expression operand ) { - Expression e = EXPcreate( Type_Expression ); - - e->e.op_code = op; - e->e.op1 = operand; - return e; -} - -/** -** \param local local identifier for source elements -** \param aggregate source aggregate to query -** \returns the query expression created -** Create a query Expression. -** NOTE Dec 2011 - MP - function description did not match actual params. Had to guess. -*/ -Expression QUERYcreate( Symbol * local, Expression aggregate ) { - Expression e = EXPcreate_from_symbol( Type_Query, local ); - Scope s = SCOPEcreate_tiny( OBJ_QUERY ); - Expression e2 = EXPcreate_from_symbol( Type_Attribute, local ); - - Variable v = VARcreate( e2, Type_Attribute ); - - DICTdefine( s->symbol_table, local->name, ( Generic )v, &e2->symbol, OBJ_VARIABLE ); - e->u.query = QUERY_new(); - e->u.query->scope = s; - e->u.query->local = v; - e->u.query->aggregate = aggregate; - return e; -} - /** ** \param expression expression to evaluate ** \param experrc buffer for error code @@ -976,14 +799,14 @@ Expression QUERYcreate( Symbol * local, Expression aggregate ) { ** Compute the value of an integer expression. */ int EXPget_integer_value( Expression expression ) { - experrc = ERROR_none; + /* TODO: why is this treated differently than a type error below? */ if( expression == EXPRESSION_NULL ) { return 0; } if( expression->return_type->u.type->body->type == integer_ ) { return INT_LITget_value( expression ); } else { - experrc = ERROR_integer_expression_expected; + ERRORreport(INTEGER_EXPRESSION_EXPECTED); return 0; } } diff --git a/src/express/express.c b/src/express/express.c index 4ae48e86d..f6a027ad2 100644 --- a/src/express/express.c +++ b/src/express/express.c @@ -68,15 +68,16 @@ * */ -#include "sc_memmgr.h" #include #include #include #include +#include "express/memory.h" #include "express/basic.h" #include "express/express.h" #include "express/resolve.h" +#include "express/factory.h" #include "stack.h" #include "express/scope.h" #include "token_type.h" @@ -84,7 +85,6 @@ #include "expscan.h" #include "parse_data.h" #include "express/lexact.h" -#include "express/exp_kw.h" void * ParseAlloc( void * ( *mallocProc )( size_t ) ); void ParseFree( void * parser, void ( *freeProc )( void * ) ); @@ -94,38 +94,31 @@ void ParseTrace(FILE *TraceFILE, char *zTracePrompt); Linked_List EXPRESS_path; int EXPRESSpass; -void ( *EXPRESSinit_args ) PROTO( ( int, char ** ) ) = 0; -void ( *EXPRESSinit_parse ) PROTO( ( void ) ) = 0; -int ( *EXPRESSfail ) PROTO( ( Express ) ) = 0; -int ( *EXPRESSsucceed ) PROTO( ( Express ) ) = 0; -void ( *EXPRESSbackend ) PROTO( ( Express ) ) = 0; +void ( *EXPRESSinit_args )( int, char ** ) = NULL; +void ( *EXPRESSinit_parse )( void ) = NULL; +int ( *EXPRESSfail )( Express ) = NULL; +int ( *EXPRESSsucceed )( Express ) = NULL; +void ( *EXPRESSbackend )( Express ) = NULL; char * EXPRESSprogram_name; extern char EXPRESSgetopt_options[]; /* initialized elsewhere */ -int ( *EXPRESSgetopt ) PROTO( ( int, char * ) ) = 0; +int ( *EXPRESSgetopt )( int, char * ) = NULL; bool EXPRESSignore_duplicate_schemas = false; +Function funcdef(char *name, int pcount, Type ret_typ); +void procdef(char *name, int pcount); +void BUILTINSinitialize(); Dictionary EXPRESSbuiltins; /* procedures/functions */ -Error ERROR_bail_out = ERROR_none; -Error ERROR_syntax = ERROR_none; -Error ERROR_unlabelled_param_type = ERROR_none; -Error ERROR_file_unreadable; -Error ERROR_file_unwriteable; -Error ERROR_warn_unsupported_lang_feat; -Error ERROR_warn_small_real; struct Scope_ * FUNC_NVL; struct Scope_ * FUNC_USEDIN; extern Express yyexpresult; -static Error ERROR_ref_nonexistent; -static Error ERROR_tilde_expansion_failed; -static Error ERROR_schema_not_in_own_schema_file; extern Linked_List PARSEnew_schemas; void SCOPEinitialize( void ); -static Express PARSERrun PROTO( ( char *, FILE * ) ); +static Express PARSERrun( char *, FILE * ); /** name specified on command line */ char * input_filename = 0; @@ -150,24 +143,20 @@ int EXPRESS_succeed( Express model ) { return 0; } -Symbol * EXPRESS_get_symbol( Generic e ) { - return( &( ( Express )e )->symbol ); -} - Express EXPRESScreate() { Express model = SCOPEcreate( OBJ_EXPRESS ); - model->u.express = ( struct Express_ * )sc_calloc( 1, sizeof( struct Express_ ) ); + model->u.express = ( struct Express_ * )calloc( 1, sizeof( struct Express_ ) ); return model; } void EXPRESSdestroy( Express model ) { if( model->u.express->basename ) { - sc_free( model->u.express->basename ); + free( model->u.express->basename ); } if( model->u.express->filename ) { - sc_free( model->u.express->filename ); + free( model->u.express->filename ); } - sc_free( model->u.express ); + free( model->u.express ); SCOPEdestroy( model ); } @@ -185,9 +174,9 @@ static void EXPRESS_PATHinit() { p = getenv( "EXPRESS_PATH" ); if( !p ) { /* if no EXPRESS_PATH, search current directory anyway */ - dir = ( Dir * )sc_malloc( sizeof( Dir ) ); + dir = ( Dir * )malloc( sizeof( Dir ) ); dir->leaf = dir->full; - LISTadd_last( EXPRESS_path, ( Generic )dir ); + LISTadd_last( EXPRESS_path, dir ); } else { int done = 0; while( !done ) { @@ -218,13 +207,13 @@ static void EXPRESS_PATHinit() { } p++; /* leave p after terminating null */ - dir = ( Dir * )sc_malloc( sizeof( Dir ) ); + dir = ( Dir * )malloc( sizeof( Dir ) ); /* if it's just ".", make it as if it was */ /* just "" to make error messages cleaner */ - if( streq( ".", start ) ) { + if( !strcmp( ".", start ) ) { dir->leaf = dir->full; - LISTadd_last( EXPRESS_path, ( Generic )dir ); + LISTadd_last( EXPRESS_path, dir ); *( p - 1 ) = save; /* put char back where */ /* temp null was */ continue; @@ -241,7 +230,7 @@ static void EXPRESS_PATHinit() { sprintf( dir->full, "%s/", start ); dir->leaf = dir->full + length + 1; } - LISTadd_last( EXPRESS_path, ( Generic )dir ); + LISTadd_last( EXPRESS_path, dir ); *( p - 1 ) = save; /* put char back where temp null was */ } @@ -250,38 +239,23 @@ static void EXPRESS_PATHinit() { static void EXPRESS_PATHfree( void ) { LISTdo( EXPRESS_path, dir, Dir * ) - sc_free( dir ); + free( dir ); LISTod LISTfree( EXPRESS_path ); } /** inform object system about bit representation for handling pass diagnostics */ void PASSinitialize() { - OBJcreate( OBJ_PASS, UNK_get_symbol, "pass", OBJ_PASS_BITS ); } /** Initialize the Express package. */ void EXPRESSinitialize( void ) { - Function - func_abs, func_acos, func_asin, func_atan, - func_blength, - func_cos, func_exists, func_exp, func_format, - func_hibound, func_hiindex, func_length, func_lobound, - func_log, func_log10, func_log2, func_loindex, - func_odd, func_rolesof, func_sin, func_sizeof, - func_sqrt, func_tan, func_typeof, - func_value, func_value_in, func_value_unique; - Procedure - proc_insert, proc_remove; - - _MEMinitialize(); + MEMORYinitialize(); ERRORinitialize(); - OBJinitialize(); HASHinitialize(); /* comes first - used by just about everything else! */ DICTinitialize(); LISTinitialize(); /* ditto */ - ERRORinitialize_after_LIST(); STACKinitialize(); PASSinitialize(); @@ -290,6 +264,7 @@ void EXPRESSinitialize( void ) { SYMBOLinitialize(); SCOPEinitialize(); + FACTORYinitialize(); TYPEinitialize(); /* cannot come before SCOPEinitialize */ VARinitialize(); @@ -303,83 +278,8 @@ void EXPRESSinitialize( void ) { STMTinitialize(); SCANinitialize(); - - EXPRESSbuiltins = DICTcreate( 35 ); -#define funcdef(x,y,c,r) \ - x = ALGcreate(OBJ_FUNCTION);\ - x->symbol.name = y;\ - x->u.func->pcount = c; \ - x->u.func->return_type = r; \ - x->u.func->builtin = true; \ - resolved_all(x); \ - DICTdefine(EXPRESSbuiltins,y,(Generic)x,0,OBJ_FUNCTION); -#define procdef(x,y,c) x = ALGcreate(OBJ_PROCEDURE);\ - x->symbol.name = y;\ - x->u.proc->pcount = c; \ - x->u.proc->builtin = true; \ - resolved_all(x); \ - DICTdefine(EXPRESSbuiltins,y,(Generic)x,0,OBJ_PROCEDURE); - /* third arg is # of parameters */ - - /* eventually everything should be data-driven, but for now */ - /* uppercase def's are global to allow passing necessary information */ - /* into resolver */ - procdef( proc_insert, KW_INSERT, 3 ); - procdef( proc_remove, KW_REMOVE, 2 ); - - funcdef( func_abs, KW_ABS, 1, Type_Number ); - funcdef( func_acos, KW_ACOS, 1, Type_Real ); - funcdef( func_asin, KW_ASIN, 1, Type_Real ); - funcdef( func_atan, KW_ATAN, 2, Type_Real ); - funcdef( func_blength, KW_BLENGTH, 1, Type_Integer ); - funcdef( func_cos, KW_COS, 1, Type_Real ); - funcdef( func_exists, KW_EXISTS, 1, Type_Boolean ); - funcdef( func_exp, KW_EXP, 1, Type_Real ); - funcdef( func_format, KW_FORMAT, 2, Type_String ); - funcdef( func_hibound, KW_HIBOUND, 1, Type_Integer ); - funcdef( func_hiindex, KW_HIINDEX, 1, Type_Integer ); - funcdef( func_length, KW_LENGTH, 1, Type_Integer ); - funcdef( func_lobound, KW_LOBOUND, 1, Type_Integer ); - funcdef( func_log, KW_LOG, 1, Type_Real ); - funcdef( func_log10, KW_LOG10, 1, Type_Real ); - funcdef( func_log2, KW_LOG2, 1, Type_Real ); - funcdef( func_loindex, KW_LOINDEX, 1, Type_Integer ); - funcdef( FUNC_NVL, KW_NVL, 2, Type_Generic ); - funcdef( func_odd, KW_ODD, 1, Type_Logical ); - funcdef( func_rolesof, KW_ROLESOF, 1, Type_Set_Of_String ); - funcdef( func_sin, KW_SIN, 1, Type_Real ); - funcdef( func_sizeof, KW_SIZEOF, 1, Type_Integer ); - funcdef( func_sqrt, KW_SQRT, 1, Type_Real ); - funcdef( func_tan, KW_TAN, 1, Type_Real ); - funcdef( func_typeof, KW_TYPEOF, 1, Type_Set_Of_String ); - funcdef( FUNC_USEDIN, KW_USEDIN, 2, Type_Bag_Of_Generic ); - funcdef( func_value, KW_VALUE, 1, Type_Number ); - funcdef( func_value_in, KW_VALUE_IN, 2, Type_Logical ); - funcdef( func_value_unique, KW_VALUE_UNIQUE, 1, Type_Logical ); - - ERROR_bail_out = ERRORcreate( "Aborting due to internal error(s)", SEVERITY_DUMP ); - ERROR_syntax = ERRORcreate( "%s in %s %s", SEVERITY_EXIT ); - /* i.e., "syntax error in procedure foo" */ - ERROR_ref_nonexistent = ERRORcreate( "USE/REF of non-existent object (%s in schema %s)", SEVERITY_ERROR ); - ERROR_tilde_expansion_failed = ERRORcreate( - "Tilde expansion for %s failed in EXPRESS_PATH environment variable", SEVERITY_ERROR ); - ERROR_schema_not_in_own_schema_file = ERRORcreate( - "Schema %s was not found in its own schema file (%s)", SEVERITY_ERROR ); - ERROR_unlabelled_param_type = ERRORcreate( - "Return type or local variable requires type label in `%s'", SEVERITY_ERROR ); - ERROR_file_unreadable = ERRORcreate( "Could not read file %s: %s", SEVERITY_ERROR ); - ERROR_file_unwriteable = ERRORcreate( "Could not write file %s: %s", SEVERITY_ERROR ); - ERROR_warn_unsupported_lang_feat = ERRORcreate( "Unsupported language feature (%s) at %s:%d", SEVERITY_WARNING ); - ERROR_warn_small_real = ERRORcreate( "REALs with extremely small magnitude may be interpreted as zero by other EXPRESS parsers " - "(IEEE 754 float denormals are sometimes rounded to zero) - fabs(%f) <= FLT_MIN.", SEVERITY_WARNING ); - - OBJcreate( OBJ_EXPRESS, EXPRESS_get_symbol, "express file", OBJ_UNUSED_BITS ); - -/* I don't think this should be a mere warning; exppp crashes if this warning is suppressed. - * ERRORcreate_warning( "unknown_subtype", ERROR_unknown_subtype ); - */ - ERRORcreate_warning( "unsupported", ERROR_warn_unsupported_lang_feat ); - ERRORcreate_warning( "limits", ERROR_warn_small_real ); + + BUILTINSinitialize(); EXPRESS_PATHinit(); /* note, must follow defn of errors it needs! */ } @@ -388,19 +288,7 @@ void EXPRESSinitialize( void ) { void EXPRESScleanup( void ) { EXPRESS_PATHfree(); - ERRORdestroy( ERROR_bail_out ); - ERRORdestroy( ERROR_syntax ); - ERRORdestroy( ERROR_ref_nonexistent ); - ERRORdestroy( ERROR_tilde_expansion_failed ); - ERRORdestroy( ERROR_schema_not_in_own_schema_file ); - ERRORdestroy( ERROR_unlabelled_param_type ); - ERRORdestroy( ERROR_file_unreadable ); - ERRORdestroy( ERROR_file_unwriteable ); - ERRORdestroy( ERROR_warn_unsupported_lang_feat ); - ERRORdestroy( ERROR_warn_small_real ); - DICTcleanup(); - OBJcleanup(); ERRORcleanup(); RESOLVEcleanup(); TYPEcleanup(); @@ -432,7 +320,7 @@ void EXPRESSparse( Express model, FILE * fp, char * filename ) { } if( !fp ) { - ERRORreport( ERROR_file_unreadable, filename, strerror( errno ) ); + ERRORreport( FILE_UNREADABLE, filename, strerror( errno ) ); return; } @@ -446,11 +334,11 @@ void EXPRESSparse( Express model, FILE * fp, char * filename ) { int length = strlen( start ); /* drop .exp suffix if present */ - if( dot && streq( dot, ".exp" ) ) { + if( dot && !strcmp( dot, ".exp" ) ) { length -= 4; } - model->u.express->basename = ( char * )sc_malloc( length + 1 ); + model->u.express->basename = ( char * )malloc( length + 1 ); memcpy( model->u.express->basename, filename, length ); model->u.express->basename[length] = '\0'; @@ -469,7 +357,7 @@ void parserInitState(); /** start parsing a new schema file */ static Express PARSERrun( char * filename, FILE * fp ) { - extern void SCAN_lex_init PROTO( ( char *, FILE * ) ); + extern void SCAN_lex_init( char *, FILE * ); extern YYSTYPE yylval; extern int yyerrstatus; int tokenID; @@ -501,7 +389,7 @@ static Express PARSERrun( char * filename, FILE * fp ) { /* want 0 on success, 1 on invalid input, 2 on memory exhaustion */ if( yyerrstatus != 0 ) { fprintf( stderr, ">> Bailing! (yyerrstatus = %d)\n", yyerrstatus ); - ERRORreport( ERROR_bail_out ); + ERRORreport( BAIL_OUT ); /* free model and model->u.express */ return 0; } @@ -513,8 +401,6 @@ static Express PARSERrun( char * filename, FILE * fp ) { return yyexpresult; } -static void RENAMEresolve( Rename * r, Schema s ); - /** * find the final object to which a rename points * i.e., follow chain of USEs or REFs @@ -522,8 +408,8 @@ static void RENAMEresolve( Rename * r, Schema s ); * * Sept 2013 - remove unused param enum rename_type type (TODO should this be used)? */ -static Generic SCOPEfind_for_rename( Scope schema, char * name ) { - Generic result; +static void * SCOPEfind_for_rename( Scope schema, char * name ) { + void *result; Rename * rename; /* object can only appear in top level symbol table */ @@ -552,7 +438,7 @@ static Generic SCOPEfind_for_rename( Scope schema, char * name ) { } LISTdo( schema->u.schema->uselist, r, Rename * ) - if( streq( ( r->nnew ? r->nnew : r->old )->name, name ) ) { + if( !strcmp( ( r->nnew ? r->nnew : r->old )->name, name ) ) { RENAMEresolve( r, schema ); DICT_type = r->type; return( r->object ); @@ -566,8 +452,8 @@ static Generic SCOPEfind_for_rename( Scope schema, char * name ) { return 0; } -static void RENAMEresolve( Rename * r, Schema s ) { - Generic remote; +void RENAMEresolve( Rename * r, Schema s ) { + void *remote; /* if (is_resolved_rename_raw(r->old)) return;*/ if( r->object ) { @@ -579,7 +465,7 @@ static void RENAMEresolve( Rename * r, Schema s ) { } if( is_resolve_in_progress_raw( r->old ) ) { - ERRORreport_with_symbol( ERROR_circular_reference, + ERRORreport_with_symbol( CIRCULAR_REFERENCE, r->old, r->old->name ); resolve_failed_raw( r->old ); return; @@ -588,7 +474,7 @@ static void RENAMEresolve( Rename * r, Schema s ) { remote = SCOPEfind_for_rename( r->schema, r->old->name ); if( remote == 0 ) { - ERRORreport_with_symbol( ERROR_ref_nonexistent, r->old, + ERRORreport_with_symbol( REF_NONEXISTENT, r->old, r->old->name, r->schema->symbol.name ); resolve_failed_raw( r->old ); } else { @@ -665,7 +551,7 @@ Schema EXPRESSfind_schema( Dictionary modeldict, char * name ) { if( s ) { return s; } - ERRORreport( ERROR_schema_not_in_own_schema_file, + ERRORreport( SCHEMA_NOT_IN_OWN_SCHEMA_FILE, name, dir->full ); return 0; } else { @@ -692,7 +578,7 @@ static void connect_lists( Dictionary modeldict, Schema schema, Linked_List list r = ( Rename * )l->data; r->schema = EXPRESSfind_schema( modeldict, r->schema_sym->name ); if( !r->schema ) { - ERRORreport_with_symbol( ERROR_undefined_schema, + ERRORreport_with_symbol(UNDEFINED_SCHEMA, r->schema_sym, r->schema_sym->name ); resolve_failed_raw( r->old ); @@ -714,11 +600,11 @@ static void connect_schema_lists( Dictionary modeldict, Schema schema, Linked_Li sym = ( Symbol * )list->data; ref_schema = EXPRESSfind_schema( modeldict, sym->name ); if( !ref_schema ) { - ERRORreport_with_symbol( ERROR_undefined_schema, sym, sym->name ); + ERRORreport_with_symbol(UNDEFINED_SCHEMA, sym, sym->name ); resolve_failed( schema ); - list->data = 0; + list->data = NULL; } else { - list->data = ( Generic )ref_schema; + list->data = ref_schema; } LISTod } @@ -891,3 +777,60 @@ void EXPRESSresolve( Express model ) { } } } + +Function funcdef(char *name, int pcount, Type ret_typ) { + Function f = ALGcreate(OBJ_FUNCTION); + f->symbol.name = name; + f->u.func->pcount = pcount; + f->u.func->return_type = ret_typ; + f->u.func->builtin = true; + resolved_all(f); + DICTdefine(EXPRESSbuiltins, name, f, 0, OBJ_FUNCTION); + return f; +} + +void procdef(char *name, int pcount) { + Procedure p = ALGcreate(OBJ_PROCEDURE); + p->symbol.name = name; + p->u.proc->pcount = pcount; + p->u.proc->builtin = true; + resolved_all(p); + DICTdefine(EXPRESSbuiltins, name, p, 0, OBJ_PROCEDURE); +} + +void BUILTINSinitialize() { + EXPRESSbuiltins = DICTcreate( 35 ); + procdef("INSERT", 3 ); + procdef("REMOVE", 2 ); + + funcdef("ABS", 1, Type_Number ); + funcdef("ACOS", 1, Type_Real ); + funcdef("ASIN", 1, Type_Real ); + funcdef("ATAN", 2, Type_Real ); + funcdef("BLENGTH", 1, Type_Integer ); + funcdef("COS", 1, Type_Real ); + funcdef("EXISTS", 1, Type_Boolean ); + funcdef("EXP", 1, Type_Real ); + funcdef("FORMAT", 2, Type_String ); + funcdef("HIBOUND", 1, Type_Integer ); + funcdef("HIINDEX", 1, Type_Integer ); + funcdef("LENGTH", 1, Type_Integer ); + funcdef("LOBOUND", 1, Type_Integer ); + funcdef("LOG", 1, Type_Real ); + funcdef("LOG10", 1, Type_Real ); + funcdef("LOG2", 1, Type_Real ); + funcdef("LOINDEX", 1, Type_Integer ); + funcdef("ODD", 1, Type_Logical ); + funcdef("ROLESOF", 1, Type_Set_Of_String ); + funcdef("SIN", 1, Type_Real ); + funcdef("SIZEOF", 1, Type_Integer ); + funcdef("SQRT", 1, Type_Real ); + funcdef("TAN", 1, Type_Real ); + funcdef("TYPEOF", 1, Type_Set_Of_String ); + funcdef("VALUE", 1, Type_Number ); + funcdef("VALUE_IN", 2, Type_Logical ); + funcdef("VALUE_UNIQUE", 1, Type_Logical ); + + FUNC_NVL = funcdef("NVL", 2, Type_Generic ); + FUNC_USEDIN = funcdef("USEDIN", 2, Type_Bag_Of_Generic ); +} diff --git a/src/express/expscan.l b/src/express/expscan.l index de23a7546..755e21fc1 100644 --- a/src/express/expscan.l +++ b/src/express/expscan.l @@ -98,9 +98,12 @@ * * Revision 4.1 90/09/13 16:29:00 clark * BPR 2.1 alpha - * + * */ - +#include +#if !defined(isascii) && defined(__isascii) +# define isascii __isascii +#endif #include "express/basic.h" #include "express/error.h" #include "express/lexact.h" @@ -142,7 +145,7 @@ SCANnextchar(char* buffer) #endif buffer[0] = *(SCANcurrent++); if (!isascii(buffer[0])) { - ERRORreport_with_line(ERROR_nonascii_char,yylineno, + ERRORreport_with_line(NONASCII_CHAR,yylineno, 0xff & buffer[0]); buffer[0] = ' '; /* substitute space */ } @@ -224,7 +227,7 @@ integer { /* bad identifier */ [_A-Za-z]id_char* { - ERRORreport_with_line(ERROR_bad_identifier, yylineno, yytext); + ERRORreport_with_line(BAD_IDENTIFIER, yylineno, yytext); return SCANprocess_identifier_or_keyword(yytext); } @@ -235,7 +238,7 @@ integer { } "'"([^'\n]|"''")*'\n' { - ERRORreport_with_line(ERROR_unterminated_string, LINENO_FUDGE); + ERRORreport_with_line(UNTERMINATED_STRING, LINENO_FUDGE); NEWLINE; return SCANprocess_string(yytext); } @@ -245,7 +248,7 @@ integer { } '"'[^\"\n]*'\n' { - ERRORreport_with_line(ERROR_unterminated_string, LINENO_FUDGE); + ERRORreport_with_line(UNTERMINATED_STRING, LINENO_FUDGE); NEWLINE; return SCANprocess_encoded_string(yytext); } @@ -299,7 +302,7 @@ integer { } "*)" { - ERRORreport_with_line(ERROR_unmatched_close_comment, yylineno); + ERRORreport_with_line(UNMATCHED_CLOSE_COMMENT, yylineno); IGNORE_TOKEN; } @@ -316,7 +319,7 @@ integer { /* As per N15, 7.1.5.3, all other recognized chars are incorrect - DEL */ [$%&@\^{}~] { - ERRORreport_with_line(ERROR_unexpected_character,yylineno,yytext[0]); + ERRORreport_with_line(UNEXPECTED_CHARACTER,yylineno,yytext[0]); IGNORE_TOKEN; } diff --git a/src/express/factory.c b/src/express/factory.c new file mode 100644 index 000000000..daf6ee7d3 --- /dev/null +++ b/src/express/factory.c @@ -0,0 +1,375 @@ +#include "express/schema.h" +#include "express/type.h" +#include "express/expr.h" + +#include "express/dict.h" + +/* TODO: use enum? */ +Type Type_Bad; +Type Type_Unknown; +Type Type_Dont_Care; +Type Type_Runtime; +Type Type_Binary; +Type Type_Boolean; +Type Type_Enumeration; +Type Type_Expression; +Type Type_Aggregate; +Type Type_Repeat; +Type Type_Integer; +Type Type_Number; +Type Type_Real; +Type Type_String; +Type Type_String_Encoded; +Type Type_Logical; +Type Type_Set; +Type Type_Attribute; +Type Type_Entity; +Type Type_Funcall; +Type Type_Generic; +Type Type_Identifier; +Type Type_Oneof; +Type Type_Query; +Type Type_Self; +Type Type_Set_Of_String; +Type Type_Set_Of_Generic; +Type Type_Bag_Of_Generic; + +void FACTORYinitialize() { + /* Very commonly-used read-only types */ + Type_Unknown = TYPEcreate( unknown_ ); + Type_Dont_Care = TYPEcreate( special_ ); + Type_Bad = TYPEcreate( special_ ); + Type_Runtime = TYPEcreate( runtime_ ); + + Type_Enumeration = TYPEcreate( enumeration_ ); + Type_Enumeration->u.type->body->flags.shared = 1; + resolved_all( Type_Enumeration ); + + Type_Expression = TYPEcreate( op_ ); + Type_Expression->u.type->body->flags.shared = 1; + + Type_Aggregate = TYPEcreate( aggregate_ ); + Type_Aggregate->u.type->body->flags.shared = 1; + Type_Aggregate->u.type->body->base = Type_Runtime; + + Type_Integer = TYPEcreate( integer_ ); + Type_Integer->u.type->body->flags.shared = 1; + resolved_all( Type_Integer ); + + Type_Real = TYPEcreate( real_ ); + Type_Real->u.type->body->flags.shared = 1; + resolved_all( Type_Real ); + + Type_Number = TYPEcreate( number_ ); + Type_Number->u.type->body->flags.shared = 1; + resolved_all( Type_Number ); + + Type_String = TYPEcreate( string_ ); + Type_String->u.type->body->flags.shared = 1; + resolved_all( Type_String ); + + Type_String_Encoded = TYPEcreate( string_ ); + Type_String_Encoded->u.type->body->flags.shared = 1; + Type_String_Encoded->u.type->body->flags.encoded = 1; + resolved_all( Type_String ); + + Type_Logical = TYPEcreate( logical_ ); + Type_Logical->u.type->body->flags.shared = 1; + resolved_all( Type_Logical ); + + Type_Binary = TYPEcreate( binary_ ); + Type_Binary->u.type->body->flags.shared = 1; + resolved_all( Type_Binary ); + + Type_Number = TYPEcreate( number_ ); + Type_Number->u.type->body->flags.shared = 1; + resolved_all( Type_Number ); + + Type_Boolean = TYPEcreate( boolean_ ); + Type_Boolean->u.type->body->flags.shared = 1; + resolved_all( Type_Boolean ); + + Type_Generic = TYPEcreate( generic_ ); + Type_Generic->u.type->body->flags.shared = 1; + resolved_all( Type_Generic ); + + Type_Set_Of_String = TYPEcreate( set_ ); + Type_Set_Of_String->u.type->body->flags.shared = 1; + Type_Set_Of_String->u.type->body->base = Type_String; + + Type_Set_Of_Generic = TYPEcreate( set_ ); + Type_Set_Of_Generic->u.type->body->flags.shared = 1; + Type_Set_Of_Generic->u.type->body->base = Type_Generic; + + Type_Bag_Of_Generic = TYPEcreate( bag_ ); + Type_Bag_Of_Generic->u.type->body->flags.shared = 1; + Type_Bag_Of_Generic->u.type->body->base = Type_Generic; + + Type_Attribute = TYPEcreate( attribute_ ); + Type_Attribute->u.type->body->flags.shared = 1; + + Type_Entity = TYPEcreate( entity_ ); + Type_Entity->u.type->body->flags.shared = 1; + + Type_Funcall = TYPEcreate( funcall_ ); + Type_Funcall->u.type->body->flags.shared = 1; + + Type_Generic = TYPEcreate( generic_ ); + Type_Generic->u.type->body->flags.shared = 1; + + Type_Identifier = TYPEcreate( identifier_ ); + Type_Identifier->u.type->body->flags.shared = 1; + + Type_Repeat = TYPEcreate( integer_ ); + Type_Repeat->u.type->body->flags.shared = 1; + Type_Repeat->u.type->body->flags.repeat = 1; + + Type_Oneof = TYPEcreate( oneof_ ); + Type_Oneof->u.type->body->flags.shared = 1; + + Type_Query = TYPEcreate( query_ ); + Type_Query->u.type->body->flags.shared = 1; + + Type_Self = TYPEcreate( self_ ); + Type_Self->u.type->body->flags.shared = 1; +} + +/** Create and return an empty scope inside a parent scope. */ +Scope SCOPEcreate( char type ) { + Scope d = SCOPE_new(); + d->symbol_table = DICTcreate( 50 ); + d->type = type; + return d; +} + +Scope SCOPEcreate_tiny( char type ) { + Scope d = SCOPE_new(); + d->symbol_table = DICTcreate( 1 ); + d->type = type; + return d; +} + +void SCOPEdestroy( Scope scope ) { + SCOPE_destroy( scope ); +} + +/** + * create a scope without a symbol table + * used for simple types + */ +Scope SCOPEcreate_nostab( char type ) { + Scope d = SCOPE_new(); + d->type = type; + return d; +} + +/** Create and return a schema. */ +Schema SCHEMAcreate( void ) { + Scope s = SCOPEcreate( OBJ_SCHEMA ); + s->enum_table = DICTcreate(50); + s->u.schema = SCHEMA_new(); + return s; +} + +/** + * create a type with no symbol table + */ +Type TYPEcreate_nostab( struct Symbol_ *symbol, Scope scope, char objtype ) { + Type t = SCOPEcreate_nostab( OBJ_TYPE ); + TypeHead th = TYPEHEAD_new(); + + t->u.type = th; + t->symbol = *symbol; + DICTdefine( scope->symbol_table, symbol->name, t, &t->symbol, objtype ); + + return t; +} + +/** + * create a type but this is just a shell, either to be completed later + * such as enumerations (which have a symbol table added later) + * or to be used as a type reference + */ +Type TYPEcreate_name( Symbol * symbol ) { + Scope s = SCOPEcreate_nostab( OBJ_TYPE ); + TypeHead t = TYPEHEAD_new(); + + s->u.type = t; + s->symbol = *symbol; + return s; +} + +Type TYPEcreate( enum type_enum type ) { + TypeBody tb = TYPEBODYcreate( type ); + Type t = TYPEcreate_from_body_anonymously( tb ); + return( t ); +} + +Type TYPEcreate_from_body_anonymously( TypeBody tb ) { + Type t = SCOPEcreate_nostab( OBJ_TYPE ); + TypeHead th = TYPEHEAD_new(); + + t->u.type = th; + t->u.type->body = tb; + t->symbol.name = 0; + SYMBOLset( t ); + return t; +} + +TypeBody TYPEBODYcreate( enum type_enum type ) { + TypeBody tb = TYPEBODY_new(); + tb->type = type; + return tb; +} + +Symbol * SYMBOLcreate( char * name, int line, const char * filename ) { + Symbol * sym = SYMBOL_new(); + sym->name = name; + sym->line = line; + sym->filename = filename; /* NOTE this used the global 'current_filename', + * instead of 'filename'. This func is only + * called in two places, and both calls use + * 'current_filename'. Changed this to avoid + * potential future headaches. (MAP, Jan 12) + */ + return sym; +} + +/** +** low-level function for type Entity +** +** \note The attribute list of a new entity is defined as an +** empty list; all other aspects of the entity are initially +** undefined (i.e., have appropriate NULL values). +*/ +Entity ENTITYcreate( Symbol * sym ) { + Scope s = SCOPEcreate( OBJ_ENTITY ); + + s->u.entity = ENTITY_new(); + s->u.entity->attributes = LISTcreate(); + s->u.entity->inheritance = ENTITY_INHERITANCE_UNINITIALIZED; + + /* it's so useful to have a type hanging around for each entity */ + s->u.entity->type = TYPEcreate_name( sym ); + s->u.entity->type->u.type->body = TYPEBODYcreate( entity_ ); + s->u.entity->type->u.type->body->entity = s; + return( s ); +} + +/** VARcreate +** \param name name of variable to create +** \param type type of new variable +** \return the Variable created +** Create and return a new variable. +** +** \note The reference class of the variable is, by default, +** dynamic. Special flags associated with the variable +** (e.g., optional) are initially false. +*/ +Variable VARcreate( Expression name, Type type ) { + Variable v = VAR_new(); + v->name = name; + v->type = type; + return v; +} + +Expression EXPcreate( Type type ) { + Expression e; + e = EXP_new(); + SYMBOLset( e ); + e->type = type; + e->return_type = Type_Unknown; + return( e ); +} + +/** + * use this when the return_type is the same as the type + * For example, for constant integers + */ +Expression EXPcreate_simple( Type type ) { + Expression e; + e = EXP_new(); + SYMBOLset( e ); + e->type = e->return_type = type; + return( e ); +} + +Expression EXPcreate_from_symbol( Type type, Symbol * symbol ) { + Expression e; + e = EXP_new(); + e->type = type; + e->return_type = Type_Unknown; + e->symbol = *symbol; + return e; +} + +/** +** \param op operation +** \param operand1 - first operand +** \param operand2 - second operand +** \param operand3 - third operand +** \returns Ternary_Expression - the expression created +** Create a ternary operation Expression. +*/ +Expression TERN_EXPcreate( Op_Code op, Expression operand1, Expression operand2, Expression operand3 ) { + Expression e = EXPcreate( Type_Expression ); + + e->e.op_code = op; + e->e.op1 = operand1; + e->e.op2 = operand2; + e->e.op3 = operand3; + return e; +} + +/** +** \fn BIN_EXPcreate +** \param op operation +** \param operand1 - first operand +** \param operand2 - second operand +** \returns Binary_Expression - the expression created +** Create a binary operation Expression. +*/ +Expression BIN_EXPcreate( Op_Code op, Expression operand1, Expression operand2 ) { + Expression e = EXPcreate( Type_Expression ); + + e->e.op_code = op; + e->e.op1 = operand1; + e->e.op2 = operand2; + return e; +} + +/** +** \param op operation +** \param operand operand +** \returns the expression created +** Create a unary operation Expression. +*/ +Expression UN_EXPcreate( Op_Code op, Expression operand ) { + Expression e = EXPcreate( Type_Expression ); + + e->e.op_code = op; + e->e.op1 = operand; + return e; +} + +/** +** \param local local identifier for source elements +** \param aggregate source aggregate to query +** \returns the query expression created +** Create a query Expression. +** NOTE Dec 2011 - MP - function description did not match actual params. Had to guess. +*/ +Expression QUERYcreate( Symbol * local, Expression aggregate ) { + Expression e = EXPcreate_from_symbol( Type_Query, local ); + Scope s = SCOPEcreate_tiny( OBJ_QUERY ); + Expression e2 = EXPcreate_from_symbol( Type_Attribute, local ); + + Variable v = VARcreate( e2, Type_Attribute ); + + DICTdefine( s->symbol_table, local->name, v, &e2->symbol, OBJ_VARIABLE ); + e->u.query = QUERY_new(); + e->u.query->scope = s; + e->u.query->local = v; + e->u.query->aggregate = aggregate; + return e; +} diff --git a/src/express/fedex.c b/src/express/fedex.c index efad8e4d9..efca9ddd1 100644 --- a/src/express/fedex.c +++ b/src/express/fedex.c @@ -71,13 +71,11 @@ * */ -#include -#include -#include -#include "sc_version_string.h" #include #include -#include "sc_getopt.h" + +#include "config.h" +#include "sc_export.h" #include "express/error.h" #include "express/express.h" #include "express/resolve.h" @@ -87,11 +85,73 @@ extern int exp_yydebug; #endif /*YYDEBUG*/ +char * sc_optarg; // global argument pointer +int sc_optind = 0; // global argv index + +int sc_getopt( int argc, char * argv[], char * optstring ) { + static char * next = NULL; + if( sc_optind == 0 ) { + next = NULL; + } + + sc_optarg = NULL; + + if( next == NULL || *next == '\0' ) { + if( sc_optind == 0 ) { + sc_optind++; + } + + if( sc_optind >= argc || argv[sc_optind][0] != '-' || argv[sc_optind][1] == '\0' ) { + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + if( strcmp( argv[sc_optind], "--" ) == 0 ) { + sc_optind++; + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + next = argv[sc_optind]; + next++; // skip past - + sc_optind++; + } + + char c = *next++; + char * cp = strchr( optstring, c ); + + if( cp == NULL || c == ':' ) { + return '?'; + } + + cp++; + if( *cp == ':' ) { + if( *next != '\0' ) { + sc_optarg = next; + next = NULL; + } else if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + sc_optind++; + } else { + return '?'; + } + } + + return c; +} + + char EXPRESSgetopt_options[256] = "Bbd:e:i:w:p:rvz"; /* larger than the string because exp2cxx, exppp, etc may append their own options */ static int no_need_to_work = 0; /* TRUE if we can exit gracefully without doing any work */ void print_fedex_version( void ) { - fprintf( stderr, "Build info for %s: %s\nhttp://github.com/stepcode/stepcode and scl-dev on google groups\n", EXPRESSprogram_name, sc_version ); + fprintf( stderr, "Build info for %s: %s\nhttp://github.com/stepcode/stepcode and scl-dev on google groups\n", EXPRESSprogram_name, SC_VERSION ); no_need_to_work = 1; } diff --git a/src/express/generated/CMakeLists.txt b/src/express/generated/CMakeLists.txt new file mode 100644 index 000000000..53e9293be --- /dev/null +++ b/src/express/generated/CMakeLists.txt @@ -0,0 +1,8 @@ +include_directories(.) + +add_library(objlib_expscan_c OBJECT expscan.c) +set_property(TARGET objlib_expscan_c PROPERTY POSITION_INDEPENDENT_CODE ON) + +add_library(objlib_expparse_c OBJECT expparse.c) +set_property(TARGET objlib_expparse_c PROPERTY POSITION_INDEPENDENT_CODE ON) + diff --git a/src/express/generated/README b/src/express/generated/README index 7ca0ac13a..fef02da84 100644 --- a/src/express/generated/README +++ b/src/express/generated/README @@ -5,21 +5,4 @@ lexing and parsing logic. DO NOT EDIT THESE FILES. They are machine generated and should not be modified directly - bugs in these files need to be fixed in either the -Perplex/RE2C/Lemon input files or the tools themselves. Directly changing -these files will result in a build failure. - -If changes need to be made, the correct approach is: - -1. install Perplex, RE2C, and Lemon -2. make any necessary fixes to the input files and/or the generator tools. -3. run the build, and copy the new generated expscan and expparse c and h - files to this directory. -4. run the build target "express_md5gen" to generate a new verification_info.cmake - file, and copy that file into this directory as well. - -The verification_info.cmake file in this directory is used by CMake to protect -the integrity of the generated files. - -If iterative debugging is necessary, set the cmake configure variable -DEBUGGING_GENERATED_SOURCES to avoid having to update generated sources and md5 -sums each time an input file is changed. +Perplex/RE2C/Lemon input files or the tools themselves. diff --git a/src/express/generated/expparse.c b/src/express/generated/expparse.c index f8f9b6a58..393d5c303 100644 --- a/src/express/generated/expparse.c +++ b/src/express/generated/expparse.c @@ -57,7 +57,7 @@ YYSTYPE yylval; Express yyexpresult; /* hook to everything built by parser */ Symbol *interface_schema; /* schema of interest in use/ref clauses */ - void (*interface_func)(); /* func to attach rename clauses */ + void (*interface_func)(struct Scope_ *, Symbol *, Symbol *, Symbol *); /* func to attach rename clauses */ /* record schemas found in a single parse here, allowing them to be */ /* differentiated from other schemas parsed earlier */ @@ -112,7 +112,7 @@ YYSTYPE yylval; #define ERROR(code) ERRORreport(code, yylineno) -void parserInitState() +void parserInitState( void ) { scope = scopes; /* no need to define scope->this */ @@ -2348,8 +2348,7 @@ static void yy_reduce( Symbol sym; sym.line = yylineno; sym.filename = current_filename; - ERRORreport_with_symbol(ERROR_unlabelled_param_type, &sym, - CURRENT_SCOPE_NAME); + ERRORreport_with_symbol(UNLABELLED_PARAM_TYPE, &sym, CURRENT_SCOPE_NAME); } } #line 2356 "expparse.c" @@ -3298,7 +3297,7 @@ static void yy_reduce( Symbol sym; sym.line = yylineno; sym.filename = current_filename; - ERRORreport_with_symbol(ERROR_unlabelled_param_type, &sym, + ERRORreport_with_symbol(UNLABELLED_PARAM_TYPE, &sym, CURRENT_SCOPE_NAME); } } @@ -3397,14 +3396,14 @@ static void yy_reduce( case 155: /* rename ::= TOK_IDENTIFIER */ #line 1342 "expparse.y" { - (*interface_func)(CURRENT_SCOPE, interface_schema, yymsp[0].minor.yy0, yymsp[0].minor.yy0); + (*interface_func)(CURRENT_SCOPE, interface_schema, yymsp[0].minor.yy0.symbol, yymsp[0].minor.yy0.symbol); } #line 3403 "expparse.c" break; case 156: /* rename ::= TOK_IDENTIFIER TOK_AS TOK_IDENTIFIER */ #line 1346 "expparse.y" { - (*interface_func)(CURRENT_SCOPE, interface_schema, yymsp[-2].minor.yy0, yymsp[0].minor.yy0); + (*interface_func)(CURRENT_SCOPE, interface_schema, yymsp[-2].minor.yy0.symbol, yymsp[0].minor.yy0.symbol); } #line 3410 "expparse.c" break; @@ -3578,7 +3577,7 @@ static void yy_reduce( Symbol sym; sym.line = yylineno; sym.filename = current_filename; - ERRORreport_with_symbol(ERROR_warn_small_real, &sym, yymsp[0].minor.yy0.rVal ); + ERRORreport_with_symbol(WARN_SMALL_REAL, &sym, yymsp[0].minor.yy0.rVal ); } if( fabs( yymsp[0].minor.yy0.rVal ) < DBL_MIN ) { yygotominor.yy401 = LITERAL_ZERO; @@ -4464,7 +4463,7 @@ static void yy_syntax_error( sym.line = yylineno; sym.filename = current_filename; - ERRORreport_with_symbol(ERROR_syntax, &sym, "Syntax error", + ERRORreport_with_symbol(SYNTAX, &sym, "Syntax error", CURRENT_SCOPE_TYPE_PRINTABLE, CURRENT_SCOPE_NAME); #line 4470 "expparse.c" ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ diff --git a/src/express/generated/expscan.c b/src/express/generated/expscan.c index d05ec736b..0b60210cb 100644 --- a/src/express/generated/expscan.c +++ b/src/express/generated/expscan.c @@ -99,6 +99,10 @@ * Revision 4.1 90/09/13 16:29:00 clark * BPR 2.1 alpha * */ +#include +#if !defined(isascii) && defined(__isascii) +# define isascii __isascii +#endif #include "express/basic.h" #include "express/error.h" #include "express/lexact.h" @@ -135,7 +139,7 @@ SCANbuffer.numRead--; #endif buffer[0] = *(SCANcurrent++); if (!isascii(buffer[0])) { -ERRORreport_with_line(ERROR_nonascii_char,yylineno, +ERRORreport_with_line(NONASCII_CHAR,yylineno, 0xff & buffer[0]); buffer[0] = ' '; /* substitute space */ } @@ -617,7 +621,7 @@ getTokenText(perplex_t scanner) #define yyextra scanner->extra static perplex_t -newScanner() +newScanner(void) { perplex_t scanner; scanner = (perplex_t)calloc(1, sizeof(struct perplex)); @@ -933,7 +937,7 @@ IGNORE_TOKEN; ++scanner->cursor; yy13: { -ERRORreport_with_line(ERROR_unexpected_character,yylineno,yytext[0]); +ERRORreport_with_line(UNEXPECTED_CHARACTER,yylineno,yytext[0]); IGNORE_TOKEN; } yy14: @@ -1093,7 +1097,7 @@ return TOK_RIGHT_BRACKET; } goto yy65; yy55: { -ERRORreport_with_line(ERROR_bad_identifier, yylineno, yytext); +ERRORreport_with_line(BAD_IDENTIFIER, yylineno, yytext); return SCANprocess_identifier_or_keyword(yytext); } yy56: @@ -1453,7 +1457,7 @@ IGNORE_TOKEN; yy105: ++scanner->cursor; { -ERRORreport_with_line(ERROR_unmatched_close_comment, yylineno); +ERRORreport_with_line(UNMATCHED_CLOSE_COMMENT, yylineno); IGNORE_TOKEN; } yy107: @@ -1497,7 +1501,7 @@ return SCANprocess_string(yytext); yy115: ++scanner->cursor; { -ERRORreport_with_line(ERROR_unterminated_string, LINENO_FUDGE); +ERRORreport_with_line(UNTERMINATED_STRING, LINENO_FUDGE); NEWLINE; return SCANprocess_string(yytext); } @@ -1527,7 +1531,7 @@ return SCANprocess_binary_literal(yytext); yy122: ++scanner->cursor; { -ERRORreport_with_line(ERROR_unterminated_string, LINENO_FUDGE); +ERRORreport_with_line(UNTERMINATED_STRING, LINENO_FUDGE); NEWLINE; return SCANprocess_encoded_string(yytext); } diff --git a/src/express/generated/verification_info.cmake b/src/express/generated/verification_info.cmake deleted file mode 100644 index 078ca43d5..000000000 --- a/src/express/generated/verification_info.cmake +++ /dev/null @@ -1,7 +0,0 @@ -# Autogenerated verification information -set(baseline_expscan_l_md5 c86358d3e57ce6916c28a63262fad6e6) -set(baseline_expparse_y_md5 91c889ef1f177533bcc581a735273b5e) -set(baseline_expscan_c_md5 b6b239869e4c7d169107fe45f760ffa0) -set(baseline_expscan_h_md5 3052c058a37045b43f96e4c04039bce3) -set(baseline_expparse_c_md5 f10b7efa5c5e35aa57b8a1050f22901a) -set(baseline_expparse_h_md5 e4a5599839b2a9f7a6915a0dcc7747b0) diff --git a/src/express/generated/ybreaks.txt b/src/express/generated/ybreaks.txt new file mode 100644 index 000000000..cb7636ff3 --- /dev/null +++ b/src/express/generated/ybreaks.txt @@ -0,0 +1,229 @@ +expparse.y:2 +expparse.y:124 +expparse.y:2440 +expparse.y:297 +expparse.y:303 +expparse.y:320 +expparse.y:337 +expparse.y:341 +expparse.y:347 +expparse.y:353 +expparse.y:359 +expparse.y:364 +expparse.y:369 +expparse.y:379 +expparse.y:387 +expparse.y:397 +expparse.y:411 +expparse.y:423 +expparse.y:442 +expparse.y:456 +expparse.y:463 +expparse.y:475 +expparse.y:486 +expparse.y:491 +expparse.y:501 +expparse.y:506 +expparse.y:510 +expparse.y:516 +expparse.y:523 +expparse.y:529 +expparse.y:533 +expparse.y:538 +expparse.y:543 +expparse.y:547 +expparse.y:551 +expparse.y:557 +expparse.y:583 +expparse.y:593 +expparse.y:599 +expparse.y:609 +expparse.y:618 +expparse.y:628 +expparse.y:634 +expparse.y:642 +expparse.y:646 +expparse.y:653 +expparse.y:658 +expparse.y:663 +expparse.y:668 +expparse.y:675 +expparse.y:694 +expparse.y:726 +expparse.y:733 +expparse.y:738 +expparse.y:745 +expparse.y:760 +expparse.y:775 +expparse.y:786 +expparse.y:819 +expparse.y:834 +expparse.y:841 +expparse.y:855 +expparse.y:862 +expparse.y:868 +expparse.y:872 +expparse.y:878 +expparse.y:907 +expparse.y:913 +expparse.y:919 +expparse.y:925 +expparse.y:931 +expparse.y:937 +expparse.y:943 +expparse.y:949 +expparse.y:955 +expparse.y:961 +expparse.y:967 +expparse.y:973 +expparse.y:979 +expparse.y:985 +expparse.y:995 +expparse.y:1001 +expparse.y:1007 +expparse.y:1013 +expparse.y:1019 +expparse.y:1025 +expparse.y:1031 +expparse.y:1037 +expparse.y:1055 +expparse.y:1059 +expparse.y:1064 +expparse.y:1087 +expparse.y:1092 +expparse.y:1098 +expparse.y:1104 +expparse.y:1129 +expparse.y:1138 +expparse.y:1146 +expparse.y:1154 +expparse.y:1159 +expparse.y:1169 +expparse.y:1178 +expparse.y:1182 +expparse.y:1188 +expparse.y:1194 +expparse.y:1202 +expparse.y:1211 +expparse.y:1224 +expparse.y:1232 +expparse.y:1240 +expparse.y:1245 +expparse.y:1253 +expparse.y:1265 +expparse.y:1278 +expparse.y:1284 +expparse.y:1292 +expparse.y:1296 +expparse.y:1300 +expparse.y:1308 +expparse.y:1313 +expparse.y:1318 +expparse.y:1324 +expparse.y:1342 +expparse.y:1346 +expparse.y:1355 +expparse.y:1365 +expparse.y:1378 +expparse.y:1384 +expparse.y:1397 +expparse.y:1420 +expparse.y:1432 +expparse.y:1437 +expparse.y:1444 +expparse.y:1452 +expparse.y:1460 +expparse.y:1487 +expparse.y:1521 +expparse.y:1529 +expparse.y:1536 +expparse.y:1548 +expparse.y:1565 +expparse.y:1571 +expparse.y:1577 +expparse.y:1583 +expparse.y:1599 +expparse.y:1616 +expparse.y:1640 +expparse.y:1646 +expparse.y:1651 +expparse.y:1658 +expparse.y:1664 +expparse.y:1681 +expparse.y:1686 +expparse.y:1691 +expparse.y:1696 +expparse.y:1707 +expparse.y:1711 +expparse.y:1716 +expparse.y:1720 +expparse.y:1730 +expparse.y:1735 +expparse.y:1742 +expparse.y:1750 +expparse.y:1760 +expparse.y:1786 +expparse.y:1794 +expparse.y:1801 +expparse.y:1810 +expparse.y:1819 +expparse.y:1827 +expparse.y:1835 +expparse.y:1842 +expparse.y:1846 +expparse.y:1850 +expparse.y:1854 +expparse.y:1858 +expparse.y:1862 +expparse.y:1866 +expparse.y:1870 +expparse.y:1878 +expparse.y:1886 +expparse.y:1891 +expparse.y:1896 +expparse.y:1907 +expparse.y:1915 +expparse.y:1936 +expparse.y:1942 +expparse.y:1949 +expparse.y:1957 +expparse.y:1984 +expparse.y:1993 +expparse.y:2012 +expparse.y:2023 +expparse.y:2036 +expparse.y:2041 +expparse.y:2090 +expparse.y:2100 +expparse.y:2106 +expparse.y:2112 +expparse.y:2118 +expparse.y:2131 +expparse.y:2137 +expparse.y:2143 +expparse.y:2149 +expparse.y:2153 +expparse.y:2158 +expparse.y:2169 +expparse.y:2175 +expparse.y:2180 +expparse.y:2185 +expparse.y:2190 +expparse.y:2215 +expparse.y:2223 +expparse.y:2234 +expparse.y:2241 +expparse.y:2284 +expparse.y:2292 +expparse.y:2297 +expparse.y:2301 +expparse.y:2328 +expparse.y:2334 +expparse.y:2341 +expparse.y:2347 +expparse.y:2362 +expparse.y:2371 +expparse.y:2377 +expparse.y:2391 +expparse.y:2396 +expparse.y:2424 diff --git a/src/express/hash.c b/src/express/hash.c index 48c968a7d..f6de3b9f3 100644 --- a/src/express/hash.c +++ b/src/express/hash.c @@ -105,20 +105,17 @@ * */ -#include #include -#include #include -#include "express/hash.h" +#include -struct freelist_head HASH_Table_fl; -struct freelist_head HASH_Element_fl; +#include "express/hash.h" /* ** Internal routines */ -static_inline Address HASHhash( char *, Hash_Table ); +static inline Address HASHhash( char *, Hash_Table ); static void HASHexpand_table( Hash_Table ); /* @@ -135,12 +132,6 @@ static long HashAccesses, HashCollisions; void HASHinitialize() { - if( HASH_Table_fl.size_elt == 0 ) { - MEMinitialize( &HASH_Table_fl, sizeof( struct Hash_Table_ ), 50, 50 ); - } - if( HASH_Element_fl.size_elt == 0 ) { - MEMinitialize( &HASH_Element_fl, sizeof( struct Element_ ), 500, 100 ); - } } Hash_Table @@ -301,7 +292,7 @@ HASHdestroy( Hash_Table table ) { p = q; } } - sc_free( table->Directory[i] ); + free( table->Directory[i] ); } } HASH_Table_destroy( table ); @@ -409,7 +400,7 @@ HASHsearch( Hash_Table table, Element item, Action action ) { ** Internal routines */ -static_inline Address HASHhash( char * Key, Hash_Table table ) { +static inline Address HASHhash( char * Key, Hash_Table table ) { Address h, address; register unsigned char * k = ( unsigned char * )Key; diff --git a/src/express/info.c b/src/express/info.c index 1669102a1..bacc2f564 100644 --- a/src/express/info.c +++ b/src/express/info.c @@ -4,14 +4,6 @@ #include "express/info.h" #include "express/express.h" -#ifndef SCHEMA_SCANNER -# include "sc_version_string.h" -#else - /* dummy string to make the compiler happy when building the schema scanner, - * should never be seen by users */ - const char * sc_version = "ERROR: version unknown / SCHEMA_SCANNER defined in libexpress!"; -#endif - char * EXPRESSversion( void ) { return( "Express Language, IS (N65), October 24, 1994" ); } @@ -19,16 +11,14 @@ char * EXPRESSversion( void ) { void EXPRESSusage( int _exit ) { fprintf( stderr, "usage: %s [-v] [-d #] [-p ] {-w|-i } express_file\n", EXPRESSprogram_name ); fprintf( stderr, "where\t-v produces the following version description:\n" ); - fprintf( stderr, "Build info for %s: %s\nhttp://github.com/stepcode/stepcode\n", EXPRESSprogram_name, sc_version ); + fprintf( stderr, "Build info for %s: %s\nhttp://github.com/stepcode/stepcode\n", EXPRESSprogram_name, SC_VERSION ); fprintf( stderr, "\t-d turns on debugging (\"-d 0\" describes this further\n" ); fprintf( stderr, "\t-p turns on printing when processing certain objects (see below)\n" ); fprintf( stderr, "\t-w warning enable\n" ); fprintf( stderr, "\t-i warning ignore\n" ); fprintf( stderr, "and is one of:\n" ); fprintf( stderr, "\tnone\n\tall\n" ); - LISTdo( ERRORwarnings, opt, Error_Warning ) - fprintf( stderr, "\t%s\n", opt->name ); - LISTod + fprintf( stderr, "%s", ERRORget_warnings_help( "\t", "\n" ) ); fprintf( stderr, "and is one or more of:\n" ); fprintf( stderr, " e entity\n" ); fprintf( stderr, " p procedure\n" ); diff --git a/src/express/lexact.c b/src/express/lexact.c index 0be65803b..d0ae80a28 100644 --- a/src/express/lexact.c +++ b/src/express/lexact.c @@ -51,17 +51,17 @@ * prettied up interface to print_objects_when_running */ -#include #include #include +#include + #include "express/lexact.h" -#include "string.h" #include "express/linklist.h" #include "stack.h" #include "express/hash.h" #include "express/express.h" #include "express/dict.h" -#include "express/memory.h" +#include "express/alloc.h" #include "token_type.h" #include "expparse.h" #include "expscan.h" @@ -72,17 +72,6 @@ Scan_Buffer SCAN_buffers[SCAN_NESTING_DEPTH]; int SCAN_current_buffer = 0; char * SCANcurrent; -Error ERROR_include_file = ERROR_none; -Error ERROR_unmatched_close_comment = ERROR_none; -Error ERROR_unmatched_open_comment = ERROR_none; -Error ERROR_unterminated_string = ERROR_none; -Error ERROR_encoded_string_bad_digit = ERROR_none; -Error ERROR_encoded_string_bad_count = ERROR_none; -Error ERROR_bad_identifier = ERROR_none; -Error ERROR_unexpected_character = ERROR_none; -Error ERROR_nonascii_char; - - extern int yylineno; #define SCAN_COMMENT_LENGTH 256 @@ -246,44 +235,13 @@ void SCANinitialize( void ) { keyword_dictionary = HASHcreate( 100 ); /* not exact */ for( k = keywords; k->key; k++ ) { - DICTdefine( keyword_dictionary, k->key, ( Generic )k, 0, OBJ_UNKNOWN ); + DICTdefine( keyword_dictionary, k->key, k, NULL, OBJ_UNKNOWN ); /* not "unknown", but certainly won't be looked up by type! */ } - - /* set up errors on first time through */ - if( ERROR_include_file == ERROR_none ) { - ERROR_include_file = - ERRORcreate( "Could not open include file `%s'.", SEVERITY_ERROR ); - ERROR_unmatched_close_comment = - ERRORcreate( "unmatched close comment", SEVERITY_ERROR ); - ERROR_unmatched_open_comment = - ERRORcreate( "unmatched open comment", SEVERITY_ERROR ); - ERROR_unterminated_string = - ERRORcreate( "unterminated string literal", SEVERITY_ERROR ); - ERROR_encoded_string_bad_digit = ERRORcreate( - "non-hex digit (%c) in encoded string literal", SEVERITY_ERROR ); - ERROR_encoded_string_bad_count = ERRORcreate( - "number of digits (%d) in encoded string literal is not divisible by 8", SEVERITY_ERROR ); - ERROR_bad_identifier = ERRORcreate( - "identifier (%s) cannot start with underscore", SEVERITY_ERROR ); - ERROR_unexpected_character = ERRORcreate( - "character (%c) is not a valid lexical element by itself", SEVERITY_ERROR ); - ERROR_nonascii_char = ERRORcreate( - "character (0x%x) is not in the EXPRESS character set", SEVERITY_ERROR ); - } } /** Clean up the Scan module */ void SCANcleanup( void ) { - ERRORdestroy( ERROR_include_file ); - ERRORdestroy( ERROR_unmatched_close_comment ); - ERRORdestroy( ERROR_unmatched_open_comment ); - ERRORdestroy( ERROR_unterminated_string ); - ERRORdestroy( ERROR_encoded_string_bad_digit ); - ERRORdestroy( ERROR_encoded_string_bad_count ); - ERRORdestroy( ERROR_bad_identifier ); - ERRORdestroy( ERROR_unexpected_character ); - ERRORdestroy( ERROR_nonascii_char ); } int SCANprocess_real_literal( const char * yytext ) { @@ -314,7 +272,7 @@ int SCANprocess_logical_literal( char * string ) { break; /* default will actually be triggered by 'UNKNOWN' keyword */ } - sc_free( string ); + free( string ); return TOK_LOGICAL_LITERAL; } @@ -326,7 +284,7 @@ int SCANprocess_identifier_or_keyword( const char * yytext ) { /* make uppercase copy */ len = strlen( yytext ); - dest = test_string = ( char * )sc_malloc( len + 1 ); + dest = test_string = ( char * )malloc( len + 1 ); for( src = yytext; *src; src++, dest++ ) { *dest = ( islower( *src ) ? toupper( *src ) : *src ); } @@ -342,7 +300,7 @@ int SCANprocess_identifier_or_keyword( const char * yytext ) { case TOK_LOGICAL_LITERAL: return SCANprocess_logical_literal( test_string ); default: - sc_free( test_string ); + free( test_string ); return k->token; } } @@ -402,12 +360,12 @@ int SCANprocess_encoded_string( const char * yytext ) { count = 0; for( s = yylval.string; *s; s++, count++ ) { if( !isxdigit( *s ) ) { - ERRORreport_with_line( ERROR_encoded_string_bad_digit, yylineno, *s ); + ERRORreport_with_line( ENCODED_STRING_BAD_DIGIT, yylineno, *s ); } } if( 0 != ( count % 8 ) ) { - ERRORreport_with_line( ERROR_encoded_string_bad_count, yylineno, count ); + ERRORreport_with_line( ENCODED_STRING_BAD_COUNT, yylineno, count ); } return TOK_STRING_LITERAL_ENCODED; @@ -488,7 +446,7 @@ void SCANinclude_file( char * filename ) { FILE * fp; if( ( fp = fopen( filename, "r" ) ) == NULL ) { - ERRORreport_with_line( ERROR_include_file, yylineno ); + ERRORreport_with_line( INCLUDE_FILE, yylineno ); } else { if( print_objects_while_running & OBJ_SCHEMA_BITS ) { fprintf( stderr, "parse: including %s at line %d of %s\n", @@ -515,7 +473,7 @@ void SCANupperize( char * s ) { } char * SCANstrdup( const char * s ) { - char * s2 = ( char * )sc_malloc( strlen( s ) + 1 ); + char * s2 = ( char * )malloc( strlen( s ) + 1 ); if( !s2 ) { return 0; } diff --git a/src/express/linklist.c b/src/express/linklist.c index 083b9d060..7089dd81d 100644 --- a/src/express/linklist.c +++ b/src/express/linklist.c @@ -21,21 +21,12 @@ * prettied up interface to print_objects_when_running */ -#include #include "express/linklist.h" -Error ERROR_empty_list = ERROR_none; -struct freelist_head LINK_fl; -struct freelist_head LIST_fl; - void LISTinitialize( void ) { - MEMinitialize( &LINK_fl, sizeof( struct Link_ ), 500, 100 ); - MEMinitialize( &LIST_fl, sizeof( struct Linked_List_ ), 100, 50 ); - ERROR_empty_list = ERRORcreate( "Empty list in %s.", SEVERITY_ERROR ); } void LISTcleanup( void ) { - ERRORdestroy( ERROR_empty_list ); } Linked_List LISTcreate() { @@ -47,7 +38,7 @@ Linked_List LISTcreate() { Linked_List LISTcopy( Linked_List src ) { Linked_List dst = LISTcreate(); - LISTdo( src, x, Generic ) + LISTdo( src, x, void * ) LISTadd_last( dst, x ); LISTod return dst; @@ -88,7 +79,7 @@ void LISTsort( Linked_List list, int (*comp)(void*, void*)) { } void LISTswap( Link p, Link q ) { - Generic tmp; + void *tmp; if( p == LINK_NULL || q == LINK_NULL || p == q ) return; @@ -99,7 +90,7 @@ void LISTswap( Link p, Link q ) { } -Generic LISTadd_first( Linked_List list, Generic item ) { +void *LISTadd_first( Linked_List list, void *item ) { Link node; node = LINK_new(); @@ -109,7 +100,7 @@ Generic LISTadd_first( Linked_List list, Generic item ) { return item; } -Generic LISTadd_last( Linked_List list, Generic item ) { +void *LISTadd_last( Linked_List list, void *item ) { Link node; node = LINK_new(); @@ -119,7 +110,7 @@ Generic LISTadd_last( Linked_List list, Generic item ) { return item; } -Generic LISTadd_after( Linked_List list, Link link, Generic item ) { +void *LISTadd_after( Linked_List list, Link link, void *item ) { Link node; if( link == LINK_NULL ) { @@ -133,7 +124,7 @@ Generic LISTadd_after( Linked_List list, Link link, Generic item ) { return item; } -Generic LISTadd_before( Linked_List list, Link link, Generic item ) { +void *LISTadd_before( Linked_List list, Link link, void *item ) { Link node; if( link == LINK_NULL ) { @@ -151,13 +142,13 @@ Generic LISTadd_before( Linked_List list, Link link, Generic item ) { } -Generic LISTremove_first( Linked_List list ) { +void *LISTremove_first( Linked_List list ) { Link node; - Generic item; + void *item; node = list->mark->next; if( node == list->mark ) { - ERRORreport( ERROR_empty_list, "LISTremove_first" ); + ERRORreport( EMPTY_LIST, "LISTremove_first" ); return NULL; } item = node->data; @@ -166,9 +157,9 @@ Generic LISTremove_first( Linked_List list ) { return item; } -Generic LISTget_first( Linked_List list ) { +void *LISTget_first( Linked_List list ) { Link node; - Generic item; + void *item; node = list->mark->next; if( node == list->mark ) { @@ -178,9 +169,9 @@ Generic LISTget_first( Linked_List list ) { return item; } -Generic LISTget_second( Linked_List list ) { +void *LISTget_second( Linked_List list ) { Link node; - Generic item; + void *item; node = list->mark->next; if( node == list->mark ) { @@ -195,7 +186,7 @@ Generic LISTget_second( Linked_List list ) { } /** first is 1, not 0 */ -Generic LISTget_nth( Linked_List list, int n ) { +void *LISTget_nth( Linked_List list, int n ) { int count = 1; Link node; diff --git a/src/express/memory.c b/src/express/memory.c index 8b91d63ad..da4db3751 100644 --- a/src/express/memory.c +++ b/src/express/memory.c @@ -1,215 +1,98 @@ -#define MEMORY_C - -/* mem.c - memory allocator for fixed size blocks */ - -/* - -This code is replacement for malloc() and free(). It takes advantage -of the fact that all of my memory allocation is of known fixed-size -blocks. This particular implementation, however, is extremely general -and will do allocation of any number of different fixed-size blocks. - -I will just give a simple example here. To allocate struct foo's, declare a handle to the foo space as: - - struct freelist_head foo_freelist; +#include "express/memory.h" -Initialize it: +#include "express/alloc.h" +#include "express/alg.h" - memory_init(&foo_freelist,sizeof(struct foo),1000,200); +#include "express/hash.h" +#include "express/symbol.h" +#include "express/schema.h" +#include "express/type.h" -Here we have asked for an initial allocation of 1000 foo's. When that -runs out, further allocations will automatically be performed 200 -foo's at a time. (Each allocation calls sbrk() so you want to -minimize them.) +struct freelist_head HASH_Table_fl; +struct freelist_head HASH_Element_fl; -To actually allocate and deallocate foo's, it helps to define two -macros as follow: +struct freelist_head LINK_fl; +struct freelist_head LIST_fl; - #define foo_new() (struct foo *)new(&foo_freelist) - #define foo_destroy(x) destroy(&oct_freelist_head,(Freelist *)(char *)x) +struct freelist_head ERROR_OPT_fl; -Now you can say things like: +struct freelist_head SYMBOL_fl; - foo1 = foo_new(); - foo_destroy(foo1); +struct freelist_head SCOPE_fl; +struct freelist_head SCHEMA_fl; +struct freelist_head REN_fl; -*/ -#include -#include -#include -#include "express/memory.h" -#include "express/error.h" - -/* just in case we are compiling by hand */ -#ifndef ALLOC -#define ALLOC -#endif /*ALLOC*/ - -/** chop up big block into linked list of small blocks - * return 0 for failure - * \param flh freelist head - * \param bytes new memory size - */ -Freelist * create_freelist( struct freelist_head * flh, int bytes ) { - Freelist * current = ( Freelist * )malloc( bytes ); - if( current == 0 ) { - return( 0 ); - } - - flh->freelist = current; - -#ifndef NOSTAT - flh->create++; - - /* set max to point to end of freelist */ - if( ( char * )flh->freelist + bytes > ( char * )flh->max ) { - flh->max = ( char * )flh->freelist + bytes; - } -#endif - - while( ( char * )current + flh->size < - ( ( char * )flh->freelist + bytes ) ) { - current->next = ( Freelist * )( ¤t->memory + flh->size ); - current = current->next; - } - current->next = NULL; - return( current ); -} +struct freelist_head TYPEHEAD_fl; +struct freelist_head TYPEBODY_fl; -void -_MEMinitialize() { -#ifdef DEBUG_MALLOC - malloc_debug( 2 ); -#endif -} +struct freelist_head VAR_fl; -/** - * \param flh freelist head - * \param size size of a single element - * \param alloc1 number to allocate initially - * \param alloc2 number to allocate if we run out - */ -void MEMinitialize( struct freelist_head * flh, unsigned int size, int alloc1, int alloc2 ) { - flh->size_elt = size; /* kludge for calloc-like behavior */ -#ifndef NOSTAT - flh->alloc = flh->dealloc = flh->create = 0; - flh->max = 0; -#endif - - /* make block large enough to hold the linked list pointer */ - flh->size = ( size > sizeof( Freelist * ) ? size : sizeof( Freelist * ) ); - /* set up for future allocations */ - flh->bytes = flh->size * alloc2; - -#ifdef REAL_MALLOC - return; - /*NOTREACHED*/ -#else - if( 0 == create_freelist( flh, flh->size * alloc1 ) ) { - ERRORnospace(); - } - -#ifdef SPACE_PROFILE - flh->count = 0; -#endif /*SPACE_PROFILE*/ - -#endif -} +struct freelist_head ENTITY_fl; -Generic MEM_new( struct freelist_head * flh ) { - Generic obj; +struct freelist_head CASE_IT_fl; -#ifndef NOSTAT - flh->alloc++; -#endif +struct freelist_head EXP_fl; +struct freelist_head OP_fl; +struct freelist_head QUERY_fl; +struct freelist_head QUAL_ATTR_fl; -#ifdef REAL_MALLOC - return( calloc( 1, flh->size_elt ) ); - /*NOTREACHED*/ -#else - if( flh->freelist == NULL && 0 == create_freelist( flh, flh->bytes ) ) { - ERRORnospace(); - } +struct freelist_head STMT_fl; +struct freelist_head ALIAS_fl; +struct freelist_head ASSIGN_fl; +struct freelist_head CASE_fl; +struct freelist_head COMP_STMT_fl; +struct freelist_head COND_fl; +struct freelist_head LOOP_fl; +struct freelist_head PCALL_fl; +struct freelist_head RET_fl; +struct freelist_head INCR_fl; - obj = &flh->freelist->memory; - flh->freelist = flh->freelist->next; +void MEMORYinitialize() { + _ALLOCinitialize(); + + ALLOCinitialize( &HASH_Table_fl, sizeof( struct Hash_Table_ ), 50, 50 ); + ALLOCinitialize( &HASH_Element_fl, sizeof( struct Element_ ), 500, 100 ); -#ifndef NOSTAT - if( obj > flh->max ) { - abort(); - } -#endif + ALLOCinitialize( &LINK_fl, sizeof( struct Link_ ), 500, 100 ); + ALLOCinitialize( &LIST_fl, sizeof( struct Linked_List_ ), 100, 50 ); -#ifdef SPACE_PROFILE - flh->count++; -#endif /*SPACE_PROFILE*/ + ALLOCinitialize( &SYMBOL_fl, sizeof( struct Symbol_ ), 100, 100 ); + + ALLOCinitialize( &SCOPE_fl, sizeof( struct Scope_ ), 100, 50 ); + + ALLOCinitialize( &TYPEHEAD_fl, sizeof( struct TypeHead_ ), 500, 100 ); + ALLOCinitialize( &TYPEBODY_fl, sizeof( struct TypeBody_ ), 200, 100 ); - /* calloc-like */ - memset( obj, 0, flh->size_elt ); + ALLOCinitialize( &VAR_fl, sizeof( struct Variable_ ), 100, 50 ); - return( obj ); -#endif -} + ALLOCinitialize( &FUNC_fl, sizeof( struct Function_ ), 100, 50 ); + ALLOCinitialize( &RULE_fl, sizeof( struct Rule_ ), 100, 50 ); + ALLOCinitialize( &PROC_fl, sizeof( struct Procedure_ ), 100, 50 ); + ALLOCinitialize( &WHERE_fl, sizeof( struct Where_ ), 100, 50 ); -void MEM_destroy( struct freelist_head * flh, Freelist * link ) { -#ifndef NOSTAT - flh->dealloc++; -#endif + ALLOCinitialize( &ENTITY_fl, sizeof( struct Entity_ ), 500, 100 ); + + ALLOCinitialize( &SCHEMA_fl, sizeof( struct Schema_ ), 40, 20 ); + ALLOCinitialize( &REN_fl, sizeof( struct Rename ), 30, 30 ); + + ALLOCinitialize( &CASE_IT_fl, sizeof( struct Case_Item_ ), 500, 100 ); -#ifdef REAL_MALLOC - free( link ); - return; - /*NOTREACHED*/ -#else + ALLOCinitialize( &EXP_fl, sizeof( struct Expression_ ), 500, 200 ); + ALLOCinitialize( &OP_fl, sizeof( struct Op_Subexpression ), 500, 100 ); + ALLOCinitialize( &QUERY_fl, sizeof( struct Query_ ), 50, 10 ); + ALLOCinitialize( &QUAL_ATTR_fl, sizeof( struct Query_ ), 20, 10 ); - link->next = flh->freelist; - flh->freelist = link; + ALLOCinitialize( &STMT_fl, sizeof( struct Statement_ ), 500, 100 ); -#ifdef SPACE_PROFILE - flh->count--; -#endif /*SPACE_PROFILE*/ + ALLOCinitialize( &ALIAS_fl, sizeof( struct Alias_ ), 10, 10 ); + ALLOCinitialize( &ASSIGN_fl, sizeof( struct Assignment_ ), 100, 30 ); + ALLOCinitialize( &CASE_fl, sizeof( struct Case_Statement_ ), 100, 30 ); + ALLOCinitialize( &COMP_STMT_fl, sizeof( struct Compound_Statement_ ), 100, 30 ); + ALLOCinitialize( &COND_fl, sizeof( struct Conditional_ ), 100, 30 ); + ALLOCinitialize( &LOOP_fl, sizeof( struct Loop_ ), 100, 30 ); + ALLOCinitialize( &PCALL_fl, sizeof( struct Procedure_Call_ ), 100, 30 ); + ALLOCinitialize( &RET_fl, sizeof( struct Return_Statement_ ), 100, 30 ); + ALLOCinitialize( &INCR_fl, sizeof( struct Increment_ ), 100, 30 ); -#endif } -#ifdef ALLOC_MAIN -struct freelist_head oct_freelist; - -#define new_oct() (struct oct *)new(&oct_freelist) -#define destroy_oct(oct) (destroy(&oct_freelist,(Freelist *)(char *)oct)) - -struct oct { - char a[16]; -}; - -main() { - struct oct * o1, *o2, *o3, *o4, *o5, *o6; - - memory_init( &oct_freelist, sizeof( struct oct ), 5, 2 ); - - o1 = new_oct(); - fprintf( stderr, "o1 = %x\n", o1 ); - o2 = new_oct(); - fprintf( stderr, "o2 = %x\n", o2 ); - o3 = new_oct(); - fprintf( stderr, "o3 = %x\n", o3 ); - o4 = new_oct(); - fprintf( stderr, "o4 = %x\n", o4 ); - o5 = new_oct(); - fprintf( stderr, "o5 = %x\n", o5 ); - o6 = new_oct(); - fprintf( stderr, "o6 = %x\n", o6 ); - destroy_oct( o1 ); - destroy_oct( o2 ); - o1 = new_oct(); - fprintf( stderr, "o1 = %x\n", o1 ); - o2 = new_oct(); - fprintf( stderr, "o2 = %x\n", o2 ); - o3 = new_oct(); - fprintf( stderr, "o3 = %x\n", o3 ); - o4 = new_oct(); - fprintf( stderr, "o4 = %x\n", o4 ); - o5 = new_oct(); - fprintf( stderr, "o5 = %x\n", o5 ); -} -#endif /*ALLOC_MAIN*/ diff --git a/src/express/object.c b/src/express/object.c index f3782a5c3..f75e64274 100644 --- a/src/express/object.c +++ b/src/express/object.c @@ -21,39 +21,85 @@ * prettied up interface to print_objects_when_running */ -#include -#include #include "express/object.h" -struct Object * OBJ; +#include "express/scope.h" +#include "express/variable.h" +#include "express/alg.h" +#include "express/schema.h" +#include "express/type.h" +#include "express/expr.h" -Symbol * UNK_get_symbol( Generic x ) { +Symbol * SCOPE_get_symbol( void *s ); +Symbol * EXPRESS_get_symbol( void *e ); +Symbol * RENAME_get_symbol( void *r ); +Symbol * TYPE_get_symbol( void *t ); +Symbol * EXP_get_symbol( void *e ); +Symbol * WHERE_get_symbol( void *w ); +Symbol * VAR_get_symbol( void *v ); +Symbol * UNK_get_symbol( void *x ); + +/* global Object type array */ +struct Object OBJ[] = { + [0] = {UNK_get_symbol, "of unknown type", 0}, + + [OBJ_VARIABLE] = {VAR_get_symbol, "variable", OBJ_VARIABLE_BITS}, + [OBJ_ENTITY] = {SCOPE_get_symbol, "entity", OBJ_ENTITY_BITS}, + + [OBJ_EXPRESSION] = {EXP_get_symbol, "expression", OBJ_EXPRESSION_BITS}, + [OBJ_AMBIG_ENUM] = {EXP_get_symbol, "ambiguous enumeration", OBJ_UNUSED_BITS}, + + [OBJ_RULE] = {SCOPE_get_symbol, "rule", OBJ_UNUSED_BITS}, + [OBJ_PROCEDURE] = {SCOPE_get_symbol, "procedure", OBJ_PROCEDURE_BITS}, + [OBJ_FUNCTION] = {SCOPE_get_symbol, "function", OBJ_FUNCTION_BITS}, + [OBJ_WHERE] = {WHERE_get_symbol, "where", OBJ_WHERE_BITS}, + + [OBJ_SCHEMA] = {SCOPE_get_symbol, "schema", OBJ_SCHEMA_BITS}, + /* TODO: PASS should also have a symbol */ + [OBJ_PASS] = {UNK_get_symbol, "pass", OBJ_PASS_BITS}, + [OBJ_EXPRESS] = {EXPRESS_get_symbol, "express file", OBJ_UNUSED_BITS}, + [OBJ_RENAME] = {RENAME_get_symbol, "rename clause", OBJ_UNUSED_BITS}, + + [OBJ_TYPE] = {TYPE_get_symbol, "type", OBJ_TYPE_BITS}, + [OBJ_TAG] = {TYPE_get_symbol, "tag", OBJ_TYPE_BITS}, + + [OBJ_ALIAS] = {SCOPE_get_symbol, "alias scope", OBJ_UNUSED_BITS }, + [OBJ_INCREMENT] = {SCOPE_get_symbol, "increment scope", OBJ_UNUSED_BITS }, + + {0} +}; + +Symbol * UNK_get_symbol( void *x ) { (void) x; /* quell unused param warning; it appears that the prototype must match other functions */ fprintf( stderr, "OBJget_symbol called on object of unknown type\n" ); ERRORabort( 0 ); return 0; } -/** Initialize the Object module */ -void OBJinitialize() { - int i; +Symbol * VAR_get_symbol( void *v ) { + return &( ( Variable )v )->name->symbol; +} + +Symbol * SCOPE_get_symbol( void *s ) { + return &( ( Scope )s )->symbol; +} + +Symbol * EXP_get_symbol( void *e ) { + return &( ( Expression )e )->symbol; +} + +Symbol * WHERE_get_symbol( void *w ) { + return ( ( Where )w )->label; +} - OBJ = ( struct Object * )sc_malloc( MAX_OBJECT_TYPES * sizeof( struct Object ) ); - for( i = 0; i < MAX_OBJECT_TYPES; i++ ) { - OBJ[i].get_symbol = UNK_get_symbol; - OBJ[i].type = "of unknown_type"; - OBJ[i].bits = 0; - } +Symbol * EXPRESS_get_symbol( void *e ) { + return &( ( Express )e )->symbol; } -/** Clean up the Object module */ -void OBJcleanup() { - sc_free( OBJ ); +Symbol * RENAME_get_symbol( void *r ) { + return ( ( Rename * )r )->old; } -void OBJcreate( char type, struct Symbol_ * ( *get_symbol )( Generic ), char * printable_type, int bits ) { - int index = ( int )type; - OBJ[index].get_symbol = get_symbol; - OBJ[index].type = printable_type; - OBJ[index].bits = bits; +Symbol * TYPE_get_symbol( void *t ) { + return &( ( Type )t )->symbol; } diff --git a/src/express/ordered_attrs.cc b/src/express/ordered_attrs.cc index 7ee41e635..8081c16e3 100644 --- a/src/express/ordered_attrs.cc +++ b/src/express/ordered_attrs.cc @@ -1,8 +1,10 @@ /// \file ordered_attrs.cc - create a list of attributes in the proper order for part 21, taking into account derivation, diamond inheritance, and (TODO) redefinition -#include "ordered_attrs.h" #include -#include +#include +#include + +#include "ordered_attrs.h" #ifdef _WIN32 # define strcasecmp _stricmp @@ -48,7 +50,7 @@ void populateAttrList( oaList & list, Entity ent ) { } LISTod } -///compare attr name and creator, remove all but first occurence +///compare attr name and creator, remove all but first occurrence ///this is necessary for diamond inheritance void dedupList( oaList & list ) { oaList::iterator it, jt; diff --git a/src/express/parse_data.h b/src/express/parse_data.h index 9ff1f96f4..fc7d41e0b 100644 --- a/src/express/parse_data.h +++ b/src/express/parse_data.h @@ -1,6 +1,10 @@ #ifndef PARSE_DATA #define PARSE_DATA #include "expscan.h" + +/* TODO: factor out when regenerating the parser */ +#define Generic void * + typedef struct parse_data { perplex_t scanner; } parse_data_t; diff --git a/src/express/resolve.c b/src/express/resolve.c index e9d01436c..fa5797917 100644 --- a/src/express/resolve.c +++ b/src/express/resolve.c @@ -56,57 +56,14 @@ */ #include -#include #include + #include "express/resolve.h" -#include "stack.h" #include "express/schema.h" #include "express/express.h" int print_objects_while_running = 0; -Error ERROR_undefined_attribute = ERROR_none; -Error ERROR_undefined_type = ERROR_none; -Error ERROR_undefined_schema = ERROR_none; -Error ERROR_unknown_attr_in_entity = ERROR_none; -Error ERROR_unknown_subtype = ERROR_none; -Error ERROR_unknown_supertype = ERROR_none; -Error ERROR_circular_reference = ERROR_none; -Error ERROR_ambiguous_attribute = ERROR_none; -Error ERROR_ambiguous_group = ERROR_none; -Error WARNING_fn_skip_branch = ERROR_none; -Error WARNING_case_skip_label = ERROR_none; - - -static void ENTITYresolve_subtypes PROTO( ( Schema ) ); -static void ENTITYresolve_supertypes PROTO( ( Entity ) ); -static void TYPEresolve_expressions PROTO( ( Type, Scope ) ); - -static Error ERROR_wrong_arg_count; -static Error ERROR_supertype_resolve; -static Error ERROR_subtype_resolve; -static Error ERROR_not_a_type; -static Error ERROR_funcall_not_a_function; -static Error ERROR_undefined_func; -static Error ERROR_undefined; -static Error ERROR_expected_proc; -static Error ERROR_no_such_procedure; -static Error ERROR_query_requires_aggregate; -static Error ERROR_self_is_unknown; -static Error ERROR_inverse_bad_attribute; -static Error ERROR_inverse_bad_entity; -static Error ERROR_missing_supertype; -static Error ERROR_subsuper_loop; -static Error ERROR_subsuper_continuation; -static Error ERROR_select_loop; -static Error ERROR_select_continuation; -static Error ERROR_type_is_entity; -static Error ERROR_overloaded_attribute; -static Error ERROR_redecl_no_such_attribute; -static Error ERROR_redecl_no_such_supertype; -static Error ERROR_missing_self; -static Error WARNING_unique_qual_redecl; - static Type self = 0; /**< always points to current value of SELF or 0 if none */ static bool found_self; /**< remember whether we've seen a SELF in a WHERE clause */ @@ -115,160 +72,14 @@ static bool found_self; /**< remember whether we've seen a SELF in a WHERE clau /* function prototypes */ /***********************/ -static int WHEREresolve PROTO( ( Linked_List, Scope, int ) ); -extern void VAR_resolve_expressions PROTO( ( Variable, Entity ) ); -extern void VAR_resolve_types PROTO( ( Variable v ) ); +extern void VAR_resolve_types( Variable v ); /** Initialize the Fed-X second pass. */ void RESOLVEinitialize( void ) { - ERROR_undefined = ERRORcreate( - "Reference to undefined object %s.", SEVERITY_ERROR ); - - ERROR_undefined_attribute = ERRORcreate( - "Reference to undefined attribute %s.", SEVERITY_ERROR ); - - ERROR_undefined_type = ERRORcreate( - "Reference to undefined type %s.", SEVERITY_ERROR ); - - ERROR_undefined_schema = ERRORcreate( - "Reference to undefined schema %s.", SEVERITY_ERROR ); - - ERROR_unknown_attr_in_entity = ERRORcreate( - "Unknown attribute %s in entity %s.", SEVERITY_ERROR ); - - ERROR_unknown_subtype = ERRORcreate( - "Unknown subtype %s for entity %s.", SEVERITY_EXIT ); - /*"Unknown subtype %s for entity %s.", SEVERITY_WARNING);*/ - - ERROR_unknown_supertype = ERRORcreate( - "Unknown supertype %s for entity %s.", SEVERITY_ERROR ); - - ERROR_circular_reference = ERRORcreate( - "Circularity: definition of %s references itself.", SEVERITY_ERROR ); - /*"Circular definition: schema %s referenced schema %s.",SEVERITY_ERROR);*/ - - ERROR_subsuper_loop = ERRORcreate( - "Entity %s is a subtype of itself", SEVERITY_ERROR ); - ERROR_subsuper_continuation = ERRORcreate( - " (via supertype entity %s)", SEVERITY_ERROR ); - - ERROR_select_loop = ERRORcreate( - "Select type %s selects itself", SEVERITY_ERROR ); - ERROR_select_continuation = ERRORcreate( - " (via select type %s)", SEVERITY_ERROR ); - - ERROR_supertype_resolve = ERRORcreate( - "Supertype %s is not an entity (line %d).", SEVERITY_ERROR ); - - ERROR_subtype_resolve = ERRORcreate( - "Subtype %s resolves to non-entity %s on line %d.", SEVERITY_ERROR ); - - ERROR_not_a_type = ERRORcreate( - "Expected a type (or entity) but %s is %s.", SEVERITY_ERROR ); - - ERROR_funcall_not_a_function = ERRORcreate( - "Function call of %s which is not a function.", SEVERITY_ERROR ); - - ERROR_undefined_func = ERRORcreate( - "Function %s undefined.", SEVERITY_ERROR ); - - ERROR_expected_proc = ERRORcreate( - "%s is used as a procedure call but is not defined as one (line %d).", SEVERITY_ERROR ); - - ERROR_no_such_procedure = ERRORcreate( - "No such procedure as %s.", SEVERITY_ERROR ); - - ERROR_wrong_arg_count = ERRORcreate( - "Call to %s uses %d arguments, but expected %d.", SEVERITY_WARNING ); - - ERROR_query_requires_aggregate = ERRORcreate( - "Query expression source must be an aggregate.", SEVERITY_ERROR ); - - ERROR_self_is_unknown = ERRORcreate( - "SELF is not within an entity declaration.", SEVERITY_ERROR ); - - ERROR_inverse_bad_entity = ERRORcreate( - "Attribute %s is referenced from non-entity-inheriting type.", SEVERITY_ERROR ); - - ERROR_inverse_bad_attribute = ERRORcreate( - "Unknown attribute %s in entity %s in inverse.", SEVERITY_ERROR ); - - ERROR_missing_supertype = ERRORcreate( - "Entity %s missing from supertype list for subtype %s.", SEVERITY_ERROR ); - - ERROR_type_is_entity = ERRORcreate( - "An entity (%s) is not acceptable as an underlying type.", SEVERITY_ERROR ); - - ERROR_ambiguous_attribute = ERRORcreate( - "Ambiguous attribute reference %s.", SEVERITY_WARNING ); - - ERROR_ambiguous_group = ERRORcreate( - "Ambiguous group reference %s.", SEVERITY_WARNING ); - - ERROR_overloaded_attribute = ERRORcreate( - "Attribute %s already inherited via supertype %s.", SEVERITY_ERROR ); - - ERROR_redecl_no_such_attribute = ERRORcreate( - "Redeclared attribute %s not declared in supertype %s.", SEVERITY_ERROR ); - - ERROR_redecl_no_such_supertype = ERRORcreate( - "No such supertype %s for redeclaration of attribute %s.", SEVERITY_ERROR ); - - ERROR_missing_self = ERRORcreate( - "Domain rule %s must refer to SELF or attribute.", SEVERITY_ERROR ); - - WARNING_fn_skip_branch = ERRORcreate( - "IF statement condition is always %s. Ignoring branch that is never taken.", SEVERITY_WARNING ); - - WARNING_case_skip_label = ERRORcreate( "CASE label %s cannot be matched. Ignoring its statements.", SEVERITY_WARNING ); - - WARNING_unique_qual_redecl = ERRORcreate( "Possibly unnecessary qualifiers on redeclared attr '%s' in a uniqueness rule of entity '%s'.", SEVERITY_WARNING ); - - ERRORcreate_warning( "circular_subtype", ERROR_subsuper_loop ); - ERRORcreate_warning( "circular_select", ERROR_select_loop ); - ERRORcreate_warning( "entity_as_type", ERROR_type_is_entity ); - ERRORcreate_warning( "invariant_condition", WARNING_fn_skip_branch ); - ERRORcreate_warning( "invalid_case", WARNING_case_skip_label ); - ERRORcreate_warning( "unnecessary_qualifiers", WARNING_unique_qual_redecl ); } /** Clean up the Fed-X second pass */ void RESOLVEcleanup( void ) { - ERRORdestroy( ERROR_undefined ); - ERRORdestroy( ERROR_undefined_attribute ); - ERRORdestroy( ERROR_undefined_type ); - ERRORdestroy( ERROR_undefined_schema ); - ERRORdestroy( ERROR_unknown_attr_in_entity ); - ERRORdestroy( ERROR_unknown_subtype ); - ERRORdestroy( ERROR_unknown_supertype ); - ERRORdestroy( ERROR_circular_reference ); - ERRORdestroy( ERROR_subsuper_loop ); - ERRORdestroy( ERROR_subsuper_continuation ); - ERRORdestroy( ERROR_select_loop ); - ERRORdestroy( ERROR_select_continuation ); - ERRORdestroy( ERROR_supertype_resolve ); - ERRORdestroy( ERROR_subtype_resolve ); - ERRORdestroy( ERROR_not_a_type ); - ERRORdestroy( ERROR_funcall_not_a_function ); - ERRORdestroy( ERROR_undefined_func ); - ERRORdestroy( ERROR_expected_proc ); - ERRORdestroy( ERROR_no_such_procedure ); - ERRORdestroy( ERROR_wrong_arg_count ); - ERRORdestroy( ERROR_query_requires_aggregate ); - ERRORdestroy( ERROR_self_is_unknown ); - ERRORdestroy( ERROR_inverse_bad_entity ); - ERRORdestroy( ERROR_inverse_bad_attribute ); - ERRORdestroy( ERROR_missing_supertype ); - ERRORdestroy( ERROR_type_is_entity ); - ERRORdestroy( ERROR_ambiguous_attribute ); - ERRORdestroy( ERROR_ambiguous_group ); - ERRORdestroy( ERROR_overloaded_attribute ); - ERRORdestroy( ERROR_redecl_no_such_attribute ); - ERRORdestroy( ERROR_redecl_no_such_supertype ); - ERRORdestroy( ERROR_missing_self ); - ERRORdestroy( WARNING_case_skip_label ); - ERRORdestroy( WARNING_fn_skip_branch ); - ERRORdestroy( WARNING_unique_qual_redecl ); } /** @@ -316,7 +127,7 @@ Type TYPE_retrieve_aggregate( Type t_select, Type t_agg ) { void EXP_resolve( Expression expr, Scope scope, Type typecheck ) { Function f = 0; Symbol * sym; - Generic x; + void *x; Entity e; Type t; bool func_args_checked = false; @@ -332,15 +143,13 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) { x = SCOPEfind( scope, expr->symbol.name, SCOPE_FIND_FUNCTION | SCOPE_FIND_ENTITY ); if( !x ) { - ERRORreport_with_symbol( ERROR_undefined_func, - &expr->symbol, expr->symbol.name ); + ERRORreport_with_symbol(UNDEFINED_FUNC, &expr->symbol, expr->symbol.name ); resolve_failed( expr ); break; } if( ( DICT_type != OBJ_FUNCTION ) && ( DICT_type != OBJ_ENTITY ) ) { sym = OBJget_symbol( x, DICT_type ); - ERRORreport_with_symbol( ERROR_funcall_not_a_function, - &expr->symbol, sym->name ); + ERRORreport_with_symbol(FUNCALL_NOT_A_FUNCTION, &expr->symbol, sym->name ); resolve_failed( expr ); break; } @@ -361,12 +170,11 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) { expr->return_type = f->u.func->return_type; /* do argument typechecking here if requested */ - /* currently, we just check arg count; necesary */ + /* currently, we just check arg count; necessary */ /* to NVL code later which assumes args are present */ if( LISTget_length( expr->u.funcall.list ) != f->u.func->pcount ) { - ERRORreport_with_symbol( ERROR_wrong_arg_count, - &expr->symbol, expr->symbol.name, + ERRORreport_with_symbol(WRONG_ARG_COUNT, &expr->symbol, expr->symbol.name, LISTget_length( expr->u.funcall.list ), f->u.func->pcount ); } @@ -426,7 +234,7 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) { /* assume it's a variable/attribute */ if( !x ) { - x = ( Generic )VARfind( scope, expr->symbol.name, 0 ); + x = VARfind( scope, expr->symbol.name, 0 ); } /* if not found as a variable, try as function, etc ... */ if( !x ) { @@ -455,8 +263,7 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) { if( typecheck == Type_Unknown ) { return; } else { - ERRORreport_with_symbol( ERROR_undefined, - &expr->symbol, expr->symbol.name ); + ERRORreport_with_symbol(UNDEFINED, &expr->symbol, expr->symbol.name ); resolve_failed( expr ); break; } @@ -502,8 +309,7 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) { /* but I don't think that's a problem */ if( ( ( Function )x )->u.func->pcount != 0 ) { - ERRORreport_with_symbol( ERROR_wrong_arg_count, - &expr->symbol, expr->symbol.name, 0, + ERRORreport_with_symbol(WRONG_ARG_COUNT, &expr->symbol, expr->symbol.name, 0, f->u.func->pcount ); resolve_failed( expr ); } else { @@ -535,7 +341,7 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) { found_self = true; resolved_all( expr ); } else { - ERRORreport_with_symbol( ERROR_self_is_unknown, &scope->symbol ); + ERRORreport_with_symbol(SELF_IS_UNKNOWN, &scope->symbol ); resolve_failed( expr ); } break; @@ -554,14 +360,14 @@ void EXP_resolve( Expression expr, Scope scope, Type typecheck ) { /* retrieve the common aggregate type */ t = TYPE_retrieve_aggregate( expr->return_type, 0 ); if( !t ) { - ERRORreport_with_symbol( ERROR_query_requires_aggregate, &expr->u.query->aggregate->symbol ); + ERRORreport_with_symbol(QUERY_REQUIRES_AGGREGATE, &expr->u.query->aggregate->symbol ); resolve_failed( expr ); break; } } else if( TYPEis_runtime( expr->return_type ) ) { t = Type_Runtime; } else { - ERRORreport_with_symbol( ERROR_query_requires_aggregate, &expr->u.query->aggregate->symbol ); + ERRORreport_with_symbol(QUERY_REQUIRES_AGGREGATE, &expr->u.query->aggregate->symbol ); resolve_failed( expr ); break; } @@ -606,14 +412,14 @@ int ENTITYresolve_subtype_expression( Expression expr, Entity ent/*was scope*/, /* must be a simple entity reference */ ent_ref = ( Entity )SCOPEfind( ent->superscope, expr->symbol.name, SCOPE_FIND_ENTITY ); if( !ent_ref ) { - ERRORreport_with_symbol( ERROR_unknown_subtype, &ent->symbol, + ERRORreport_with_symbol(UNKNOWN_SUBTYPE, &ent->symbol, expr->symbol.name, ent->symbol.name ); i = RESOLVE_FAILED; } else if( DICT_type != OBJ_ENTITY ) { Symbol * sym = OBJget_symbol( ent_ref, DICT_type ); /* line number should really be on supertype name, */ /* but all we have easily is the entity line number */ - ERRORreport_with_symbol( ERROR_subtype_resolve, &ent->symbol, + ERRORreport_with_symbol(SUBTYPE_RESOLVE, &ent->symbol, expr->symbol.name, sym->line ); i = RESOLVE_FAILED; } else { @@ -632,7 +438,7 @@ int ENTITYresolve_subtype_expression( Expression expr, Entity ent/*was scope*/, LISTod if( !found ) { - LISTadd_last( *flat, ( Generic )ent_ref ); + LISTadd_last( *flat, ent_ref ); } /* link in to expression */ @@ -653,7 +459,7 @@ int ENTITYresolve_subtype_expression( Expression expr, Entity ent/*was scope*/, if( !ent_ref->u.entity->supertypes ) { ent_ref->u.entity->supertypes = LISTcreate(); } - LISTadd_last( ent_ref->u.entity->supertypes, ( Generic )ent ); + LISTadd_last( ent_ref->u.entity->supertypes, ent ); } #endif } @@ -699,9 +505,9 @@ void TYPE_resolve( Type * typeaddr /*, Scope scope*/ ) { TYPEresolve( &type->u.type->head ); if( !is_resolve_failed( type->u.type->head ) ) { - if( ERRORis_enabled( ERROR_type_is_entity ) ) { + if( ERRORis_enabled( TYPE_IS_ENTITY ) ) { if( TYPEis_entity( type->u.type->head ) ) { - ERRORreport_with_symbol( ERROR_type_is_entity, &type->symbol, type->u.type->head->u.type->body->entity->symbol.name ); + ERRORreport_with_symbol(TYPE_IS_ENTITY, &type->symbol, type->u.type->head->u.type->body->entity->symbol.name ); resolve_failed( type ); } } @@ -719,7 +525,7 @@ void TYPE_resolve( Type * typeaddr /*, Scope scope*/ ) { SCOPE_FIND_ANYTHING ^ SCOPE_FIND_VARIABLE ); /* SCOPE_FIND_TYPE | SCOPE_FIND_ENTITY);*/ if( !ref_type ) { - ERRORreport_with_symbol( ERROR_undefined_type, &type->symbol, type->symbol.name ); + ERRORreport_with_symbol(UNDEFINED_TYPE, &type->symbol, type->symbol.name ); *typeaddr = Type_Bad; /* just in case */ resolve_failed( type ); } else if( DICT_type == OBJ_TYPE ) { @@ -737,7 +543,7 @@ void TYPE_resolve( Type * typeaddr /*, Scope scope*/ ) { type = *typeaddr = ( ( Entity )ref_type )->u.entity->type; } else { - ERRORreport_with_symbol( ERROR_not_a_type, &type->symbol, type->symbol.name, + ERRORreport_with_symbol(NOT_A_TYPE, &type->symbol, type->symbol.name, OBJget_type( DICT_type ) ); resolve_failed( type ); } @@ -789,7 +595,7 @@ void VAR_resolve_types( Variable v ) { type = type->u.type->body->base; } if( type->u.type->body->type != entity_ ) { - ERRORreport_with_symbol( ERROR_inverse_bad_entity, + ERRORreport_with_symbol(INVERSE_BAD_ENTITY, &v->name->symbol, v->inverse_symbol->name ); } else { attr = VARfind( type->u.type->body->entity, v->inverse_symbol->name, 1 ); @@ -797,7 +603,7 @@ void VAR_resolve_types( Variable v ) { v->inverse_attribute = attr; failed |= is_resolve_failed( attr->name ); } else { - ERRORreport_with_symbol( ERROR_inverse_bad_attribute, + ERRORreport_with_symbol(INVERSE_BAD_ATTR, v->inverse_symbol, v->inverse_symbol->name, type->u.type->body->entity->symbol.name ); } } @@ -824,7 +630,6 @@ void VAR_resolve_types( Variable v ) { ** ** Resolve all references in a statement. */ -void STMTresolve( Statement statement, Scope scope ); void STMTlist_resolve( Linked_List list, Scope scope ) { LISTdo( list, s, Statement ) @@ -898,12 +703,12 @@ void STMTresolve( Statement statement, Scope scope ) { if( proc ) { if( DICT_type != OBJ_PROCEDURE ) { Symbol * newsym = OBJget_symbol( proc, DICT_type ); - ERRORreport_with_symbol( ERROR_expected_proc, &statement->symbol, proc_name, newsym->line ); + ERRORreport_with_symbol(EXPECTED_PROC, &statement->symbol, proc_name, newsym->line ); } else { statement->u.proc->procedure = proc; } } else { - ERRORreport_with_symbol( ERROR_no_such_procedure, &statement->symbol, proc_name ); + ERRORreport_with_symbol(NO_SUCH_PROCEDURE, &statement->symbol, proc_name ); } LISTdo( statement->u.proc->parameters, e, Expression ) EXPresolve( e, scope, Type_Dont_Care ); @@ -940,24 +745,9 @@ void STMTresolve( Statement statement, Scope scope ) { } } -void ALGresolve_expressions_statements( Scope s, Linked_List statements ) { - int status = 0; - - if( print_objects_while_running & OBJ_ALGORITHM_BITS & - OBJget_bits( s->type ) ) { - fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass, - s->symbol.name, OBJget_type( s->type ) ); - } - - SCOPEresolve_expressions_statements( s ); - STMTlist_resolve( statements, s ); - - s->symbol.resolved = status; -} - static Variable ENTITY_get_local_attribute( Entity e, char * name ) { LISTdo( e->u.entity->attributes, a, Variable ) - if( streq( VARget_simple_name( a ), name ) ) { + if( !strcmp( VARget_simple_name( a ), name ) ) { return a; } LISTod; @@ -982,9 +772,9 @@ void ENTITYresolve_expressions( Entity e ) { if( attr->name->type->u.type->body->type == op_ ) { /* attribute redeclaration */ sname = attr->name->e.op1->e.op2->symbol.name; - if( streq( sname, e->symbol.name ) || + if( !strcmp( sname, e->symbol.name ) || !( sup = ENTITYfind_inherited_entity( e, sname, 0 ) ) ) { - ERRORreport_with_symbol( ERROR_redecl_no_such_supertype, + ERRORreport_with_symbol(REDECL_NO_SUCH_SUPERTYPE, &attr->name->e.op1->e.op2->symbol, attr->name->e.op1->e.op2->symbol.name, VARget_simple_name( attr ) ); @@ -992,7 +782,7 @@ void ENTITYresolve_expressions( Entity e ) { } else { sname = VARget_simple_name( attr ); if( !ENTITY_get_local_attribute( sup, sname ) ) { - ERRORreport_with_symbol( ERROR_redecl_no_such_attribute, + ERRORreport_with_symbol(REDECL_NO_SUCH_ATTR, &attr->name->e.op2->symbol, sname, sup->symbol.name ); @@ -1006,7 +796,7 @@ void ENTITYresolve_expressions( Entity e ) { LISTdo_n( e->u.entity->supertypes, supr, Entity, b ) { if( ENTITYget_named_attribute( supr, attr->name->symbol.name ) ) { - ERRORreport_with_symbol( ERROR_overloaded_attribute, + ERRORreport_with_symbol(OVERLOADED_ATTR, &attr->name->symbol, attr->name->symbol.name, supr->symbol.name ); @@ -1055,7 +845,7 @@ void ENTITYcheck_missing_supertypes( Entity ent ) { } } LISTod; if( !found ) { - ERRORreport_with_symbol( ERROR_missing_supertype, &sub->symbol, ent->symbol.name, sub->symbol.name ); + ERRORreport_with_symbol(MISSING_SUPERTYPE, &sub->symbol, ent->symbol.name, sub->symbol.name ); resolve_failed( sub ); } } LISTod; @@ -1080,7 +870,7 @@ int ENTITY_check_subsuper_cyclicity( Entity e, Entity enew ) { /* as well */ LISTdo( enew->u.entity->subtypes, sub, Entity ) if( e == sub ) { - ERRORreport_with_symbol( ERROR_subsuper_loop, &sub->symbol, e->symbol.name ); + ERRORreport_with_symbol(SUBSUPER_LOOP, &sub->symbol, e->symbol.name ); return 1; } if( sub->search_id == __SCOPE_search_id ) { @@ -1088,7 +878,7 @@ int ENTITY_check_subsuper_cyclicity( Entity e, Entity enew ) { } sub->search_id = __SCOPE_search_id; if( ENTITY_check_subsuper_cyclicity( e, sub ) ) { - ERRORreport_with_symbol( ERROR_subsuper_continuation, &sub->symbol, sub->symbol.name ); + ERRORreport_with_symbol(SUBSUPER_CONTINUATION, &sub->symbol, sub->symbol.name ); return 1; } LISTod; @@ -1105,7 +895,7 @@ int TYPE_check_select_cyclicity( TypeBody tb, Type tnew ) { LISTdo( tnew->u.type->body->list, item, Type ) if( item->u.type->body->type == select_ ) { if( tb == item->u.type->body ) { - ERRORreport_with_symbol( ERROR_select_loop, + ERRORreport_with_symbol(SELECT_LOOP, &item->symbol, item->symbol.name ); return 1; } @@ -1114,7 +904,7 @@ int TYPE_check_select_cyclicity( TypeBody tb, Type tnew ) { } item->search_id = __SCOPE_search_id; if( TYPE_check_select_cyclicity( tb, item ) ) { - ERRORreport_with_symbol( ERROR_select_continuation, + ERRORreport_with_symbol(SELECT_CONTINUATION, &item->symbol, item->symbol.name ); return 1; } @@ -1136,7 +926,7 @@ void ENTITYresolve_types( Entity e ); void SCOPEresolve_types( Scope s ) { Variable var; DictionaryEntry de; - Generic x; + void *x; if( print_objects_while_running & OBJ_SCOPE_BITS & OBJget_bits( s->type ) ) { @@ -1148,7 +938,7 @@ void SCOPEresolve_types( Scope s ) { while( 0 != ( x = DICTdo( &de ) ) ) { switch( DICT_type ) { case OBJ_TYPE: - if( ERRORis_enabled( ERROR_select_loop ) ) { + if( ERRORis_enabled( SELECT_LOOP ) ) { TYPEcheck_select_cyclicity( ( Type )x ); } break; @@ -1165,7 +955,7 @@ void SCOPEresolve_types( Scope s ) { ENTITYcheck_missing_supertypes( ( Entity )x ); ENTITYresolve_types( ( Entity )x ); ENTITYcalculate_inheritance( ( Entity )x ); - if( ERRORis_enabled( ERROR_subsuper_loop ) ) { + if( ERRORis_enabled( SUBSUPER_LOOP ) ) { ENTITYcheck_subsuper_cyclicity( ( Entity )x ); } if( is_resolve_failed( ( Entity )x ) ) { @@ -1194,52 +984,8 @@ void SCOPEresolve_types( Scope s ) { } } - - -/********************************new****************************************/ - -void SCOPEresolve_subsupers( Scope scope ) { - DictionaryEntry de; - Generic x; - char type; - Symbol * sym; - Type t; - - if( print_objects_while_running & OBJ_SCOPE_BITS & - OBJget_bits( scope->type ) ) { - fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass, - scope->symbol.name, OBJget_type( scope->type ) ); - } - - DICTdo_init( scope->symbol_table, &de ); - while( 0 != ( x = DICTdo( &de ) ) ) { - switch( type = DICT_type ) { - case OBJ_ENTITY: - ENTITYresolve_supertypes( ( Entity )x ); - ENTITYresolve_subtypes( ( Entity )x ); - break; - case OBJ_FUNCTION: - case OBJ_PROCEDURE: - case OBJ_RULE: - SCOPEresolve_subsupers( ( Scope )x ); - break; - case OBJ_TYPE: - t = ( Type )x; - TYPEresolve( &t ); - break; - default: - /* ignored everything else */ - break; - } - sym = OBJget_symbol( x, type ); - if( is_resolve_failed_raw( sym ) ) { - resolve_failed( scope ); - } - } -} - /** for each supertype, find the entity it refs to */ -static void ENTITYresolve_supertypes( Entity e ) { +void ENTITYresolve_supertypes( Entity e ) { Entity ref_entity; if( print_objects_while_running & OBJ_ENTITY_BITS ) { @@ -1259,18 +1005,18 @@ static void ENTITYresolve_supertypes( Entity e ) { LISTdo( e->u.entity->supertype_symbols, sym, Symbol * ) { ref_entity = ( Entity )SCOPEfind( e->superscope, sym->name, SCOPE_FIND_ENTITY ); if( !ref_entity ) { - ERRORreport_with_symbol( ERROR_unknown_supertype, sym, sym->name, e->symbol.name ); + ERRORreport_with_symbol(UNKNOWN_SUPERTYPE, sym, sym->name, e->symbol.name ); /* ENTITY_resolve_failed = 1;*/ resolve_failed( e ); } else if( DICT_type != OBJ_ENTITY ) { Symbol * newsym = OBJget_symbol( ref_entity, DICT_type ); - ERRORreport_with_symbol( ERROR_supertype_resolve, sym, sym->name, newsym->line ); + ERRORreport_with_symbol(SUPERTYPE_RESOLVE, sym, sym->name, newsym->line ); /* ENTITY_resolve_failed = 1;*/ resolve_failed( e ); } else { bool found = false; - LISTadd_last( e->u.entity->supertypes, ( Generic )ref_entity ); + LISTadd_last( e->u.entity->supertypes, ref_entity ); if( is_resolve_failed( ref_entity ) ) { resolve_failed( e ); } @@ -1290,13 +1036,13 @@ static void ENTITYresolve_supertypes( Entity e ) { if( !ref_entity->u.entity->subtypes ) { ref_entity->u.entity->subtypes = LISTcreate(); } - LISTadd_last( ref_entity->u.entity->subtypes, ( Generic )e ); + LISTadd_last( ref_entity->u.entity->subtypes, e ); } } } LISTod; } -static void ENTITYresolve_subtypes( Entity e ) { +void ENTITYresolve_subtypes( Entity e ) { int i; if( print_objects_while_running & OBJ_ENTITY_BITS ) { @@ -1348,7 +1094,7 @@ void ENTITYresolve_uniques( Entity e ) { if( ( attr2 ) && ( attr != attr2 ) && ( ENTITYdeclares_variable( e, attr2 ) ) ) { /* attr exists in type + supertype - it's a redeclaration. * in this case, qualifiers are unnecessary; print a warning */ - ERRORreport_with_symbol( WARNING_unique_qual_redecl, &( expr->e.op2->symbol ), expr->e.op2->symbol.name, e->symbol.name ); + ERRORreport_with_symbol(UNIQUE_QUAL_REDECL, &( expr->e.op2->symbol ), expr->e.op2->symbol.name, e->symbol.name ); } if( !attr ) { /* ERRORreport_with_symbol(ERROR_unknown_attr_in_entity,*/ @@ -1389,7 +1135,7 @@ void ENTITYresolve_types( Entity e ) { } /** resolve all expressions in type definitions */ -static void TYPEresolve_expressions( Type t, Scope s ) { +void TYPEresolve_expressions( Type t, Scope s ) { TypeBody body; /* meaning of self in a type declaration refers to the type itself, so */ @@ -1427,58 +1173,7 @@ static void TYPEresolve_expressions( Type t, Scope s ) { self = self_old; } -void SCOPEresolve_expressions_statements( Scope s ) { - DictionaryEntry de; - Generic x; - Variable v; - - if( print_objects_while_running & OBJ_SCOPE_BITS & - OBJget_bits( s->type ) ) { - fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass, - s->symbol.name, OBJget_type( s->type ) ); - } - - DICTdo_init( s->symbol_table, &de ); - while( 0 != ( x = DICTdo( &de ) ) ) { - switch( DICT_type ) { - case OBJ_SCHEMA: - if( is_not_resolvable( ( Schema )x ) ) { - break; - } - SCOPEresolve_expressions_statements( ( Scope )x ); - break; - case OBJ_ENTITY: - ENTITYresolve_expressions( ( Entity )x ); - break; - case OBJ_FUNCTION: - ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.func->body ); - break; - case OBJ_PROCEDURE: - ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.proc->body ); - break; - case OBJ_RULE: - ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.rule->body ); - - WHEREresolve( RULEget_where( ( Scope )x ), ( Scope )x, 0 ); - break; - case OBJ_VARIABLE: - v = ( Variable )x; - TYPEresolve_expressions( v->type, s ); - if( v->initializer ) { - EXPresolve( v->initializer, s, v->type ); - } - break; - case OBJ_TYPE: - TYPEresolve_expressions( ( Type )x, s ); - break; - default: - /* ignored everything else */ - break; - } - } -} - -static int WHEREresolve( Linked_List list, Scope scope, int need_self ) { +int WHEREresolve( Linked_List list, Scope scope, int need_self ) { int status = 0; LISTdo( list, w, Where ) @@ -1492,7 +1187,7 @@ static int WHEREresolve( Linked_List list, Scope scope, int need_self ) { found_self = false; EXPresolve( w->expr, scope, Type_Dont_Care ); if( need_self && ! found_self ) { - ERRORreport_with_symbol( ERROR_missing_self, + ERRORreport_with_symbol(MISSING_SELF, w->label, w->label->name ); w->label->resolved = RESOLVE_FAILED; diff --git a/src/express/resolve2.c b/src/express/resolve2.c new file mode 100644 index 000000000..bd5518595 --- /dev/null +++ b/src/express/resolve2.c @@ -0,0 +1,115 @@ +/* + * This software was developed by U.S. Government employees as part of + * their official duties and is not subject to copyright. + */ + +#include "express/express.h" +#include "express/schema.h" +#include "express/resolve.h" + +void SCOPEresolve_subsupers( Scope scope ) { + DictionaryEntry de; + void *x; + char type; + Symbol * sym; + Type t; + + if( print_objects_while_running & OBJ_SCOPE_BITS & + OBJget_bits( scope->type ) ) { + fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass, + scope->symbol.name, OBJget_type( scope->type ) ); + } + + DICTdo_init( scope->symbol_table, &de ); + while( 0 != ( x = DICTdo( &de ) ) ) { + switch( type = DICT_type ) { + case OBJ_ENTITY: + ENTITYresolve_supertypes( ( Entity )x ); + ENTITYresolve_subtypes( ( Entity )x ); + break; + case OBJ_FUNCTION: + case OBJ_PROCEDURE: + case OBJ_RULE: + SCOPEresolve_subsupers( ( Scope )x ); + break; + case OBJ_TYPE: + t = ( Type )x; + TYPEresolve( &t ); + break; + default: + /* ignored everything else */ + break; + } + sym = OBJget_symbol( x, type ); + if( is_resolve_failed_raw( sym ) ) { + resolve_failed( scope ); + } + } +} + +void SCOPEresolve_expressions_statements( Scope s ) { + DictionaryEntry de; + void *x; + Variable v; + + if( print_objects_while_running & OBJ_SCOPE_BITS & + OBJget_bits( s->type ) ) { + fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass, + s->symbol.name, OBJget_type( s->type ) ); + } + + DICTdo_init( s->symbol_table, &de ); + while( 0 != ( x = DICTdo( &de ) ) ) { + switch( DICT_type ) { + case OBJ_SCHEMA: + if( is_not_resolvable( ( Schema )x ) ) { + break; + } + SCOPEresolve_expressions_statements( ( Scope )x ); + break; + case OBJ_ENTITY: + ENTITYresolve_expressions( ( Entity )x ); + break; + case OBJ_FUNCTION: + ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.func->body ); + break; + case OBJ_PROCEDURE: + ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.proc->body ); + break; + case OBJ_RULE: + ALGresolve_expressions_statements( ( Scope )x, ( ( Scope )x )->u.rule->body ); + + WHEREresolve( RULEget_where( ( Scope )x ), ( Scope )x, 0 ); + break; + case OBJ_VARIABLE: + v = ( Variable )x; + TYPEresolve_expressions( v->type, s ); + if( v->initializer ) { + EXPresolve( v->initializer, s, v->type ); + } + break; + case OBJ_TYPE: + TYPEresolve_expressions( ( Type )x, s ); + break; + default: + /* ignored everything else */ + break; + } + } +} + +void ALGresolve_expressions_statements( Scope s, Linked_List statements ) { + int status = 0; + + if( print_objects_while_running & OBJ_ALGORITHM_BITS & + OBJget_bits( s->type ) ) { + fprintf( stderr, "pass %d: %s (%s)\n", EXPRESSpass, + s->symbol.name, OBJget_type( s->type ) ); + } + + SCOPEresolve_expressions_statements( s ); + STMTlist_resolve( statements, s ); + + s->symbol.resolved = status; +} + diff --git a/src/express/schema.c b/src/express/schema.c index 4207d262c..5dd77873a 100644 --- a/src/express/schema.c +++ b/src/express/schema.c @@ -45,64 +45,17 @@ * prettied up interface to print_objects_when_running */ -#include #include "express/expbasic.h" #include "express/schema.h" #include "express/object.h" #include "express/resolve.h" -struct freelist_head REN_fl; -struct freelist_head SCOPE_fl; -struct freelist_head SCHEMA_fl; - int __SCOPE_search_id = 0; -Symbol * RENAME_get_symbol( Generic r ) { - return( ( ( Rename * )r )->old ); -} - /** Initialize the Schema module. */ void SCHEMAinitialize( void ) { - OBJcreate( OBJ_RENAME, RENAME_get_symbol, "rename clause", OBJ_UNUSED_BITS ); - MEMinitialize( &REN_fl, sizeof( struct Rename ), 30, 30 ); - MEMinitialize( &SCHEMA_fl, sizeof( struct Schema_ ), 40, 20 ); -} - -/** Create and return an empty scope inside a parent scope. */ -Scope SCOPEcreate( char type ) { - Scope d = SCOPE_new(); - d->symbol_table = DICTcreate( 50 ); - d->type = type; - return d; -} - -Scope SCOPEcreate_tiny( char type ) { - Scope d = SCOPE_new(); - d->symbol_table = DICTcreate( 1 ); - d->type = type; - return d; } -void SCOPEdestroy( Scope scope ) { - SCOPE_destroy( scope ); -} - -/** - * create a scope without a symbol table - * used for simple types - */ -Scope SCOPEcreate_nostab( char type ) { - Scope d = SCOPE_new(); - d->type = type; - return d; -} - -/** Create and return a schema. */ -Schema SCHEMAcreate( void ) { - Scope s = SCOPEcreate( OBJ_SCHEMA ); - s->u.schema = SCHEMA_new(); - return s; -} /** SCHEMAget_name ** \param schema schema to examine @@ -143,7 +96,7 @@ void SCHEMAadd_reference( Schema cur_schema, Symbol * ref_schema, Symbol * old, if( !cur_schema->u.schema->reflist ) { cur_schema->u.schema->reflist = LISTcreate(); } - LISTadd_last( cur_schema->u.schema->reflist, ( Generic )r ); + LISTadd_last( cur_schema->u.schema->reflist, r ); } void SCHEMAadd_use( Schema cur_schema, Symbol * ref_schema, Symbol * old, Symbol * snnew ) { @@ -156,7 +109,7 @@ void SCHEMAadd_use( Schema cur_schema, Symbol * ref_schema, Symbol * old, Symbol if( !cur_schema->u.schema->uselist ) { cur_schema->u.schema->uselist = LISTcreate(); } - LISTadd_last( cur_schema->u.schema->uselist, ( Generic )r ); + LISTadd_last( cur_schema->u.schema->uselist, r ); } void SCHEMAdefine_reference( Schema schema, Rename * r ) { @@ -170,7 +123,7 @@ void SCHEMAdefine_reference( Schema schema, Rename * r ) { } if( !old || ( DICT_type != OBJ_RENAME ) || ( old->object != r->object ) ) { DICTdefine( schema->u.schema->refdict, name, - ( Generic )r, r->old, OBJ_RENAME ); + r, r->old, OBJ_RENAME ); } } @@ -185,7 +138,7 @@ void SCHEMAdefine_use( Schema schema, Rename * r ) { } if( !old || ( DICT_type != OBJ_RENAME ) || ( old->object != r->object ) ) { DICTdefine( schema->u.schema->usedict, name, - ( Generic )r, r->old, OBJ_RENAME ); + r, r->old, OBJ_RENAME ); } } @@ -225,7 +178,7 @@ Linked_List SCHEMAget_entities_use( Scope scope ) { } /** return ref'd entities */ -static void SCHEMA_get_entities_ref( Scope scope, Linked_List result ) { +void SCHEMA_get_entities_ref( Scope scope, Linked_List result ) { Rename * rename; DictionaryEntry de; diff --git a/src/express/scope.c b/src/express/scope.c index 52f5d7822..3d93509d7 100644 --- a/src/express/scope.c +++ b/src/express/scope.c @@ -39,18 +39,11 @@ * prettied up interface to print_objects_when_running */ -#include #define SCOPE_C #include "express/scope.h" #include "express/resolve.h" -Symbol * SCOPE_get_symbol( Generic s ) { - return( &( ( Scope )s )->symbol ); -} - void SCOPEinitialize( void ) { - OBJcreate( OBJ_SCHEMA, SCOPE_get_symbol, "schema", OBJ_SCHEMA_BITS ); - MEMinitialize( &SCOPE_fl, sizeof( struct Scope_ ), 100, 50 ); } /** @@ -58,7 +51,7 @@ void SCOPEinitialize( void ) { */ void SCOPE_get_entities( Scope scope, Linked_List result ) { DictionaryEntry de; - Generic x; + void *x; DICTdo_type_init( scope->symbol_table, &de, OBJ_ENTITY ); while( 0 != ( x = DICTdo( &de ) ) ) { @@ -71,7 +64,7 @@ void SCOPE_get_entities( Scope scope, Linked_List result ) { */ void SCOPE_get_functions( Scope scope, Linked_List result ) { DictionaryEntry de; - Generic x; + void *x; DICTdo_type_init( scope->symbol_table, &de, OBJ_FUNCTION ); while( 0 != ( x = DICTdo( &de ) ) ) { @@ -92,7 +85,7 @@ Linked_List SCOPEget_functions( Scope scope ) { */ void SCOPE_get_rules( Scope scope, Linked_List result ) { DictionaryEntry de; - Generic x; + void *x; DICTdo_type_init( scope->symbol_table, &de, OBJ_RULE ); while( 0 != ( x = DICTdo( &de ) ) ) { @@ -140,7 +133,7 @@ void SCOPE_dfs( Dictionary symbols, Entity root, Linked_List result ) { SCOPE_dfs( symbols, ent, result ); } LISTod - LISTadd_last( result, ( Generic )root ); + LISTadd_last( result, root ); } } @@ -170,10 +163,9 @@ Linked_List SCOPEget_entities_superclass_order( Scope scope ) { * note that object found is not actually checked, only because * caller is in a better position to describe the error with context */ -Generic SCOPEfind( Scope scope, char * name, int type ) { - extern Generic SCOPE_find( Scope , char *, int ); +void *SCOPEfind( Scope scope, char * name, int type ) { extern Dictionary EXPRESSbuiltins; /* procedures/functions */ - Generic x; + void *x; __SCOPE_search_id++; @@ -194,8 +186,8 @@ Generic SCOPEfind( Scope scope, char * name, int type ) { * the supertype/subtype hierarchy * EH??? -> lookup an object when the current scope is not a schema */ -Generic SCOPE_find( Scope scope, char * name, int type ) { - Generic result; +void *SCOPE_find( Scope scope, char * name, int type ) { + void *result; Rename * rename; if( scope->search_id == __SCOPE_search_id ) { diff --git a/src/express/stack.h b/src/express/stack.h index d0d99e14f..cb80180c9 100644 --- a/src/express/stack.h +++ b/src/express/stack.h @@ -75,12 +75,4 @@ typedef Linked_List Stack; /* function prototypes */ /***********************/ -/*******************************/ -/* inline function definitions */ -/*******************************/ - -#if supports_inline_functions || defined(STACK_C) - -#endif /* supports_inline_functions || defined(STACK_C) */ - #endif /* STACK_H */ diff --git a/src/express/stmt.c b/src/express/stmt.c index 1ac62deac..7f1579f25 100644 --- a/src/express/stmt.c +++ b/src/express/stmt.c @@ -26,7 +26,7 @@ * CADDETC certified * * Revision 1.6 1993/02/16 03:27:02 libes - * removed artifical begin/end nesting for improved reconstruction (printing) + * removed artificial begin/end nesting for improved reconstruction (printing) * of original Express file * * Revision 1.5 1992/08/18 17:13:43 libes @@ -40,21 +40,8 @@ * */ -#include #include "express/stmt.h" -struct freelist_head STMT_fl; - -struct freelist_head ALIAS_fl; -struct freelist_head ASSIGN_fl; -struct freelist_head CASE_fl; -struct freelist_head COMP_STMT_fl; -struct freelist_head COND_fl; -struct freelist_head LOOP_fl; -struct freelist_head PCALL_fl; -struct freelist_head RET_fl; -struct freelist_head INCR_fl; - Statement STATEMENT_ESCAPE = STATEMENT_NULL; Statement STATEMENT_SKIP = STATEMENT_NULL; @@ -68,21 +55,6 @@ Statement STMTcreate( int type ) { /** Initialize the Statement module. */ void STMTinitialize( void ) { - MEMinitialize( &STMT_fl, sizeof( struct Statement_ ), 500, 100 ); - - MEMinitialize( &ALIAS_fl, sizeof( struct Alias_ ), 10, 10 ); - MEMinitialize( &ASSIGN_fl, sizeof( struct Assignment_ ), 100, 30 ); - MEMinitialize( &CASE_fl, sizeof( struct Case_Statement_ ), 100, 30 ); - MEMinitialize( &COMP_STMT_fl, sizeof( struct Compound_Statement_ ), 100, 30 ); - MEMinitialize( &COND_fl, sizeof( struct Conditional_ ), 100, 30 ); - MEMinitialize( &LOOP_fl, sizeof( struct Loop_ ), 100, 30 ); - MEMinitialize( &PCALL_fl, sizeof( struct Procedure_Call_ ), 100, 30 ); - MEMinitialize( &RET_fl, sizeof( struct Return_Statement_ ), 100, 30 ); - MEMinitialize( &INCR_fl, sizeof( struct Increment_ ), 100, 30 ); - - OBJcreate( OBJ_ALIAS, SCOPE_get_symbol, "alias scope", OBJ_UNUSED_BITS ); - OBJcreate( OBJ_INCREMENT, SCOPE_get_symbol, "increment scope", OBJ_UNUSED_BITS ); - STATEMENT_SKIP = STMTcreate( STMT_SKIP ); STATEMENT_ESCAPE = STMTcreate( STMT_ESCAPE ); } @@ -205,7 +177,7 @@ Scope INCR_CTLcreate( Symbol * control, Expression start, Expression e = EXPcreate_from_symbol( Type_Attribute, control ); Variable v = VARcreate( e, Type_Number ); DICTdefine( s->symbol_table, control->name, - ( Generic )v, control, OBJ_VARIABLE ); + v, control, OBJ_VARIABLE ); s->u.incr = INCR_new(); s->u.incr->init = start; s->u.incr->end = end; diff --git a/src/express/symbol.c b/src/express/symbol.c index a70e38b5a..ed71fb836 100644 --- a/src/express/symbol.c +++ b/src/express/symbol.c @@ -32,25 +32,8 @@ * Initial revision */ -#include #include "express/symbol.h" -struct freelist_head SYMBOL_fl; - /** Initialize the Symbol module */ void SYMBOLinitialize( void ) { - MEMinitialize( &SYMBOL_fl, sizeof( struct Symbol_ ), 100, 100 ); -} - -Symbol * SYMBOLcreate( char * name, int line, const char * filename ) { - Symbol * sym = SYMBOL_new(); - sym->name = name; - sym->line = line; - sym->filename = filename; /* NOTE this used the global 'current_filename', - * instead of 'filename'. This func is only - * called in two places, and both calls use - * 'current_filename'. Changed this to avoid - * potential future headaches. (MAP, Jan 12) - */ - return sym; } diff --git a/src/express/test/CMakeLists.txt b/src/express/test/CMakeLists.txt index 2c932d3cf..413761fd3 100644 --- a/src/express/test/CMakeLists.txt +++ b/src/express/test/CMakeLists.txt @@ -1,5 +1,64 @@ include_directories(..) +if(SC_GENERATE_LP_SOURCES) + include_directories("${PERPLEX_ExpScanner_INCLUDE_DIR}" "${LEMON_ExpParser_INCLUDE_DIR}") +endif(SC_GENERATE_LP_SOURCES) + +set(EXPRESS_CORE_OBJ + # base + $ + $ + $ + $ + + # global tables + $ + $ + + # AST creation + $ + $ + $ + + # deprecated + $ + $ +) + +add_executable(test_expr driver.c test_expr.c $ ${EXPRESS_CORE_OBJ}) +add_test(NAME exp_resolve_select_enum_member COMMAND test_expr resolve_select_enum_member) +add_test(NAME exp_resolve_entity_attribute COMMAND test_expr resolve_entity_attribute) + +add_executable(test_express driver.c test_express.c $ ${EXPRESS_CORE_OBJ}) +add_test(NAME express_rename_resolve COMMAND test_express express_rename_resolve) + +add_executable(test_resolve driver.c test_resolve.c $ ${EXPRESS_CORE_OBJ}) + +add_test(NAME exp_resolve_bad_func_call COMMAND test_resolve exp_resolve_bad_func_call) +add_test(NAME exp_resolve_func_call COMMAND test_resolve exp_resolve_func_call) +add_test(NAME exp_resolve_local_identifier COMMAND test_resolve exp_resolve_local_identifier) +add_test(NAME entity_resolve_subtype_expr_entity COMMAND test_resolve entity_resolve_subtype_expr_entity) +add_test(NAME type_resolve_entity COMMAND test_resolve type_resolve_entity) +add_test(NAME stmt_resolve_pcall_proc COMMAND test_resolve stmt_resolve_pcall_proc) +add_test(NAME scope_resolve_named_types COMMAND test_resolve scope_resolve_named_types) +add_test(NAME entity_resolve_supertypes_entity COMMAND test_resolve entity_resolve_supertypes_entity) + +add_executable(test_resolve2 driver.c test_resolve2.c $ ${EXPRESS_CORE_OBJ}) +add_test(NAME scope_resolve_expr_stmt COMMAND test_resolve2 scope_resolve_expr_stmt) +add_test(NAME scope_resolve_subsupers COMMAND test_resolve2 scope_resolve_subsupers) + +add_executable(test_schema driver.c test_schema.c $ ${EXPRESS_CORE_OBJ}) +add_test(NAME schema_define_ref COMMAND test_schema schema_define_ref) +add_test(NAME schema_define_use COMMAND test_schema schema_define_use) +add_test(NAME schema_get_entities_ref COMMAND test_schema schema_get_entities_ref) +add_test(NAME var_find COMMAND test_schema var_find) + +add_executable(test_scope driver.c test_scope.c $ ${EXPRESS_CORE_OBJ}) +add_test(NAME scope_find COMMAND test_scope scope_find) + +add_executable(test_type driver.c test_type.c $ ${EXPRESS_CORE_OBJ}) +add_test(NAME type_create_user_defined_tag COMMAND test_type type_create_user_defined_tag) + add_test(NAME build_check_express WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_COMMAND} --build . @@ -15,8 +74,8 @@ add_test(NAME test_plib_parse_err set_tests_properties( test_plib_parse_err PROPERTIES DEPENDS "build_check_express;$" ) set_tests_properties( test_plib_parse_err build_check_express PROPERTIES LABELS parser ) -sc_addexec(print_schemas "../fedex.c;print_schemas.c" "express;base") -sc_addexec(print_attrs "../fedex.c;print_attrs.c" "express;base") +sc_addexec(print_schemas SOURCES ../fedex.c print_schemas.c LINK_LIBRARIES express) +sc_addexec(print_attrs SOURCES ../fedex.c print_attrs.c LINK_LIBRARIES express) # Local Variables: # tab-width: 8 diff --git a/src/express/test/driver.c b/src/express/test/driver.c new file mode 100644 index 000000000..d3e5f4dc5 --- /dev/null +++ b/src/express/test/driver.c @@ -0,0 +1,49 @@ +#include +#include + +#include "driver.h" + +#include "express/memory.h" +#include "express/factory.h" + +extern struct test_def tests[]; + +int main(int argc, char *argv[]) { + int status; + + /* enable libexpress allocator */ + MEMORYinitialize(); + FACTORYinitialize(); + + argc--; + status = 0; + if (argc) { + int test_counter = argc; + + /* selected tests */ + for (int i=1; i <= argc; i++) { + for (unsigned int j=0; tests[j].name != NULL; j++) { + const char *test_name = tests[j].name; + int (*test_ptr) (void) = tests[j].testfunc; + + if (!strcmp(argv[i], test_name)) { + test_counter--; + setup(); + status |= test_ptr(); + } + } + } + + if (test_counter) + fprintf(stderr, "WARNING: some tests not found...\n"); + } else { + /* all tests */ + for (unsigned int j=0; tests[j].name != NULL; j++) { + int (*test_ptr) (void) = tests[j].testfunc; + setup(); + status |= test_ptr(); + } + } + + return status; +} diff --git a/src/express/test/driver.h b/src/express/test/driver.h new file mode 100644 index 000000000..0df5707cd --- /dev/null +++ b/src/express/test/driver.h @@ -0,0 +1,11 @@ +#ifndef __DRIVER_H_ +#define __DRIVER_H_ + +struct test_def { + const char *name; + int (*testfunc) (void); +}; + +void setup(); + +#endif /* __DRIVER_H_ */ diff --git a/src/express/test/fff.h b/src/express/test/fff.h new file mode 100644 index 000000000..ecd19da4f --- /dev/null +++ b/src/express/test/fff.h @@ -0,0 +1,6188 @@ +/* +git origin: https://github.com/meekrosoft/fff.git +git SHA: 8b5e44b872f65874427be645dfacd01cde31f358 + +LICENSE + +The MIT License (MIT) + +Copyright (c) 2010 Michael Long + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#ifndef FAKE_FUNCTIONS +#define FAKE_FUNCTIONS + +#include +#include /* For memset and memcpy */ + +#define FFF_MAX_ARGS (20u) +#ifndef FFF_ARG_HISTORY_LEN + #define FFF_ARG_HISTORY_LEN (50u) +#endif +#ifndef FFF_CALL_HISTORY_LEN + #define FFF_CALL_HISTORY_LEN (50u) +#endif +/* -- INTERNAL HELPER MACROS -- */ +#define SET_RETURN_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \ + FUNCNAME##_fake.return_val_seq = ARRAY_POINTER; \ + FUNCNAME##_fake.return_val_seq_len = ARRAY_LEN; +#define SET_CUSTOM_FAKE_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \ + FUNCNAME##_fake.custom_fake_seq = ARRAY_POINTER; \ + FUNCNAME##_fake.custom_fake_seq_len = ARRAY_LEN; + +/* Defining a function to reset a fake function */ +#define RESET_FAKE(FUNCNAME) { \ + FUNCNAME##_reset(); \ +} \ + + +#define DECLARE_ARG(type, n, FUNCNAME) \ + type arg##n##_val; \ + type arg##n##_history[FFF_ARG_HISTORY_LEN]; + +#define DECLARE_ALL_FUNC_COMMON \ + unsigned int call_count; \ + unsigned int arg_history_len; \ + unsigned int arg_histories_dropped; \ + +#define DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + RETURN_TYPE return_val_history[FFF_ARG_HISTORY_LEN]; + +#define SAVE_ARG(FUNCNAME, n) \ + memcpy((void*)&FUNCNAME##_fake.arg##n##_val, (void*)&arg##n, sizeof(arg##n)); + +#define ROOM_FOR_MORE_HISTORY(FUNCNAME) \ + FUNCNAME##_fake.call_count < FFF_ARG_HISTORY_LEN + +#define SAVE_RET_HISTORY(FUNCNAME, RETVAL) \ + if ((FUNCNAME##_fake.call_count - 1) < FFF_ARG_HISTORY_LEN) \ + memcpy((void *)&FUNCNAME##_fake.return_val_history[FUNCNAME##_fake.call_count - 1], (const void *) &RETVAL, sizeof(RETVAL)); \ + +#define SAVE_ARG_HISTORY(FUNCNAME, ARGN) \ + memcpy((void*)&FUNCNAME##_fake.arg##ARGN##_history[FUNCNAME##_fake.call_count], (void*)&arg##ARGN, sizeof(arg##ARGN)); + +#define HISTORY_DROPPED(FUNCNAME) \ + FUNCNAME##_fake.arg_histories_dropped++ + +#define DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + RETURN_TYPE return_val; \ + int return_val_seq_len; \ + int return_val_seq_idx; \ + RETURN_TYPE * return_val_seq; \ + +#define DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + int custom_fake_seq_len; \ + int custom_fake_seq_idx; \ + +#define INCREMENT_CALL_COUNT(FUNCNAME) \ + FUNCNAME##_fake.call_count++ + +#define RETURN_FAKE_RESULT(FUNCNAME) \ + if (FUNCNAME##_fake.return_val_seq_len){ /* then its a sequence */ \ + if(FUNCNAME##_fake.return_val_seq_idx < FUNCNAME##_fake.return_val_seq_len) { \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx]) \ + return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx++]; \ + } \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]) \ + return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]; /* return last element */ \ + } \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val) \ + return FUNCNAME##_fake.return_val; \ + +#ifdef __cplusplus + #define FFF_EXTERN_C extern "C"{ + #define FFF_END_EXTERN_C } +#else /* ansi c */ + #define FFF_EXTERN_C + #define FFF_END_EXTERN_C +#endif /* cpp/ansi c */ + +#define DEFINE_RESET_FUNCTION(FUNCNAME) \ + void FUNCNAME##_reset(void){ \ + memset(&FUNCNAME##_fake, 0, sizeof(FUNCNAME##_fake)); \ + FUNCNAME##_fake.arg_history_len = FFF_ARG_HISTORY_LEN; \ + } +/* -- END INTERNAL HELPER MACROS -- */ + +typedef void (*fff_function_t)(void); +typedef struct { + fff_function_t call_history[FFF_CALL_HISTORY_LEN]; + unsigned int call_history_idx; +} fff_globals_t; + +FFF_EXTERN_C \ +extern fff_globals_t fff; +FFF_END_EXTERN_C \ + +#define DEFINE_FFF_GLOBALS \ + FFF_EXTERN_C \ + fff_globals_t fff; \ + FFF_END_EXTERN_C + +#define FFF_RESET_HISTORY() fff.call_history_idx = 0; + +#define REGISTER_CALL(function) \ + if(fff.call_history_idx < FFF_CALL_HISTORY_LEN) \ + fff.call_history[fff.call_history_idx++] = (fff_function_t)function; + +#define DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(void); \ + void(**custom_fake_seq)(void); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(void); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(void){ \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC0(FUNCNAME) \ + DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \ + DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \ + + +#define DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0); \ + void(**custom_fake_seq)(ARG0_TYPE arg0); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + SAVE_ARG(FUNCNAME, 19); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + SAVE_ARG_HISTORY(FUNCNAME, 19); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(void); \ + RETURN_TYPE(**custom_fake_seq)(void); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(void); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(void){ \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + + +#define DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + SAVE_ARG(FUNCNAME, 19); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + SAVE_ARG_HISTORY(FUNCNAME, 19); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake(arg0, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg0); \ + ret = FUNCNAME##_fake.custom_fake(arg0, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg1); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg2); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg3); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg4); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg5); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg6); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg7); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg8); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg9); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg10); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg11); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg12); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg13); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg14); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg15); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg16); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg17); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FFF_EXTERN_C \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \ + FFF_END_EXTERN_C \ + +#define DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FFF_EXTERN_C \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg18); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + FFF_END_EXTERN_C \ + +#define FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + +/* MSVC expand macro fix */ +#define EXPAND(x) x + +#define PP_NARG_MINUS2(...) EXPAND(PP_NARG_MINUS2_(__VA_ARGS__, PP_RSEQ_N_MINUS2())) + +#define PP_NARG_MINUS2_(...) EXPAND(PP_ARG_MINUS2_N(__VA_ARGS__)) + +#define PP_ARG_MINUS2_N(returnVal, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N + +#define PP_RSEQ_N_MINUS2() 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + + +#define PP_NARG_MINUS1(...) EXPAND(PP_NARG_MINUS1_(__VA_ARGS__, PP_RSEQ_N_MINUS1())) + +#define PP_NARG_MINUS1_(...) EXPAND(PP_ARG_MINUS1_N(__VA_ARGS__)) + +#define PP_ARG_MINUS1_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N + +#define PP_RSEQ_N_MINUS1() 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + + + +/* DECLARE AND DEFINE FAKE FUNCTIONS - PLACE IN TEST FILES */ + +#define FAKE_VALUE_FUNC(...) EXPAND(FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VALUE_(N,...) EXPAND(FUNC_VALUE_N(N,__VA_ARGS__)) + +#define FUNC_VALUE_N(N,...) EXPAND(FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define FAKE_VOID_FUNC(...) EXPAND(FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VOID_(N,...) EXPAND(FUNC_VOID_N(N,__VA_ARGS__)) + +#define FUNC_VOID_N(N,...) EXPAND(FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define FAKE_VALUE_FUNC_VARARG(...) EXPAND(FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VALUE_VARARG_(N,...) EXPAND(FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define FUNC_VALUE_VARARG_N(N,...) EXPAND(FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define FAKE_VOID_FUNC_VARARG(...) EXPAND(FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VOID_VARARG_(N,...) EXPAND(FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define FUNC_VOID_VARARG_N(N,...) EXPAND(FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + +/* DECLARE FAKE FUNCTIONS - PLACE IN HEADER FILES */ + +#define DECLARE_FAKE_VALUE_FUNC(...) EXPAND(DECLARE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_(N,...) EXPAND(DECLARE_FUNC_VALUE_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_N(N,...) EXPAND(DECLARE_FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define DECLARE_FAKE_VOID_FUNC(...) EXPAND(DECLARE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VOID_(N,...) EXPAND(DECLARE_FUNC_VOID_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VOID_N(N,...) EXPAND(DECLARE_FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define DECLARE_FAKE_VALUE_FUNC_VARARG(...) EXPAND(DECLARE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_VARARG_(N,...) EXPAND(DECLARE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_VARARG_N(N,...) EXPAND(DECLARE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define DECLARE_FAKE_VOID_FUNC_VARARG(...) EXPAND(DECLARE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VOID_VARARG_(N,...) EXPAND(DECLARE_FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VOID_VARARG_N(N,...) EXPAND(DECLARE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + +/* DEFINE FAKE FUNCTIONS - PLACE IN SOURCE FILES */ + +#define DEFINE_FAKE_VALUE_FUNC(...) EXPAND(DEFINE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_(N,...) EXPAND(DEFINE_FUNC_VALUE_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_N(N,...) EXPAND(DEFINE_FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define DEFINE_FAKE_VOID_FUNC(...) EXPAND(DEFINE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VOID_(N,...) EXPAND(DEFINE_FUNC_VOID_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VOID_N(N,...) EXPAND(DEFINE_FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define DEFINE_FAKE_VALUE_FUNC_VARARG(...) EXPAND(DEFINE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_VARARG_(N,...) EXPAND(DEFINE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_VARARG_N(N,...) EXPAND(DEFINE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define DEFINE_FAKE_VOID_FUNC_VARARG(...) EXPAND(DEFINE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VOID_VARARG_(N,...) EXPAND(DEFINE_FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VOID_VARARG_N(N,...) EXPAND(DEFINE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + + +#endif /* FAKE_FUNCTIONS */ diff --git a/src/express/test/print_attrs.c b/src/express/test/print_attrs.c index 881ada059..6729a70ce 100644 --- a/src/express/test/print_attrs.c +++ b/src/express/test/print_attrs.c @@ -6,7 +6,7 @@ * print_attrs -a */ -#include "sc_cf.h" +#include "config.h" #include #ifdef HAVE_SYS_PARAM_H # include diff --git a/src/express/test/print_schemas.c b/src/express/test/print_schemas.c index 40bb0a1e0..b0cba2f71 100644 --- a/src/express/test/print_schemas.c +++ b/src/express/test/print_schemas.c @@ -2,7 +2,7 @@ /* prints names of schemas used in an EXPRESS file */ /* symlink.c author: Don Libes, NIST, 20-Mar-1993 */ -#include "sc_cf.h" +#include "config.h" #include #ifdef HAVE_SYS_PARAM_H # include diff --git a/src/express/test/test_expr.c b/src/express/test/test_expr.c new file mode 100644 index 000000000..72c4d3e14 --- /dev/null +++ b/src/express/test/test_expr.c @@ -0,0 +1,195 @@ +#include + +#include "express/expr.h" + +/* core */ +#include "express/hash.h" +#include "express/linklist.h" + +/* non-core */ +#include "express/dict.h" +#include "express/variable.h" + +#include "driver.h" +#include "fff.h" + +/* + * mock globals + */ + +char * EXPRESSprogram_name; +int yylineno; +int __SCOPE_search_id; + +Error ERROR_warn_unsupported_lang_feat; +Error WARNING_case_skip_label; +Error ERROR_undefined_attribute; + +/* + * mock functions + */ + +DEFINE_FFF_GLOBALS + +FAKE_VALUE_FUNC(int, EXPRESS_fail, Express) +FAKE_VALUE_FUNC(Variable, ENTITYfind_inherited_attribute, struct Scope_ *, char *, struct Symbol_ **) +FAKE_VALUE_FUNC(Variable, ENTITYresolve_attr_ref, Entity, Symbol *, Symbol *) +FAKE_VALUE_FUNC(struct Scope_ *, ENTITYfind_inherited_entity, struct Scope_ *, char *, int) +FAKE_VOID_FUNC(EXP_resolve, Expression, Scope, Type) + +void setup() { + EXPinitialize(); + + RESET_FAKE(EXPRESS_fail); + RESET_FAKE(ENTITYfind_inherited_attribute); + RESET_FAKE(ENTITYresolve_attr_ref); + RESET_FAKE(ENTITYfind_inherited_entity); + RESET_FAKE(EXP_resolve); +} + +/* TODO: remove DICTlookup after eliminating DICT_type */ +void EXP_resolve_type_handler(Expression exp, Scope cxt, Type typ) { + (void) typ; + Type res_typ = DICTlookup(cxt->symbol_table, exp->symbol.name); + exp->type = res_typ; + exp->return_type = res_typ; + exp->symbol.resolved = RESOLVED; +} + +int test_resolve_select_enum_member() { + Schema scope; + Symbol *e_type_id, *enum_id, *s_type_id; + Type enum_typ, select_typ, chk_typ; + TypeBody tb; + Expression expr, op1, op2, exp_enum_id; + + /* + * boilerplate: create objects, populate symbol tables + */ + scope = SCHEMAcreate(); + + s_type_id = SYMBOLcreate("sel1", 1, "test1"); + e_type_id = SYMBOLcreate("enum1", 1, "test1"); + enum_id = SYMBOLcreate("val1", 1, "test1"); + + enum_typ = TYPEcreate_name(e_type_id); + enum_typ->symbol_table = DICTcreate(50); + + exp_enum_id = EXPcreate(enum_typ); + exp_enum_id->symbol = *enum_id; + exp_enum_id->u.integer = 1; + + tb = TYPEBODYcreate(enumeration_); + tb->list = LISTcreate(); + LISTadd_last(tb->list, enum_id); + enum_typ->u.type->body = tb; + + DICT_define(scope->symbol_table, e_type_id->name, enum_typ, &enum_typ->symbol, OBJ_TYPE); + + /* TODO: OBJ_ENUM / OBJ_EXPRESSION are used interchangeably, this is confusing. */ + DICT_define(scope->enum_table, exp_enum_id->symbol.name, exp_enum_id, &exp_enum_id->symbol, OBJ_EXPRESSION); + DICT_define(enum_typ->symbol_table, enum_id->name, exp_enum_id, enum_id, OBJ_EXPRESSION); + + select_typ = TYPEcreate_name(s_type_id); + tb = TYPEBODYcreate(select_); + tb->list = LISTcreate(); + LISTadd_last(tb->list, enum_typ); + select_typ->u.type->body = tb; + DICT_define(scope->symbol_table, s_type_id->name, select_typ, &select_typ->symbol, OBJ_TYPE); + + op1 = EXPcreate_from_symbol(Type_Identifier, s_type_id); + op2 = EXPcreate_from_symbol(Type_Identifier, enum_id); + expr = BIN_EXPcreate(OP_DOT, op1, op2); + + /* + * test: sel_ref '.' enum_id + * expectation: enum_typ + */ + EXP_resolve_fake.custom_fake = EXP_resolve_type_handler; + + chk_typ = EXPresolve_op_dot(expr, scope); + + assert(EXP_resolve_fake.call_count == 1); + assert(expr->e.op1->type == select_typ); + assert(chk_typ == enum_typ); + + /* in case of error SIGABRT will be raised (and non-zero returned) */ + + return 0; +} + +/* TODO: remove DICTlookup after eliminating DICT_type */ +void EXP_resolve_entity_handler(Expression exp, Scope cxt, Type unused) { + (void) unused; + Entity ent = DICTlookup(cxt->symbol_table, exp->symbol.name); + Type typ = ent->u.entity->type; + exp->type = typ; + exp->return_type = typ; + exp->symbol.resolved = RESOLVED; +} + +Variable ENTITY_resolve_attr_handler(Entity ent, Symbol *grp_ref, Symbol *attr_ref) { + (void) grp_ref; + Variable v = DICTlookup(ent->symbol_table, attr_ref->name); + return v; +} + +int test_resolve_entity_attribute() { + Schema scope; + Symbol *e_type_id, *attr_id; + Entity ent; + Type attr_typ, chk_typ; + TypeBody tb; + Expression exp_attr, expr, op1, op2; + Variable var_attr; + Linked_List explicit_attr_list; + + /* + * boilerplate: create objects, populate symbol tables + */ + scope = SCHEMAcreate(); + + e_type_id = SYMBOLcreate("entity1", 1, "test2"); + ent = ENTITYcreate(e_type_id); + DICT_define(scope->symbol_table, e_type_id->name, ent, &ent->symbol, OBJ_ENTITY); + + attr_id = SYMBOLcreate("attr1", 1, "test2"); + exp_attr = EXPcreate_from_symbol(Type_Attribute, attr_id); + tb = TYPEBODYcreate(number_); + attr_typ = TYPEcreate_from_body_anonymously(tb); + attr_typ->superscope = ent; + var_attr = VARcreate(exp_attr, attr_typ); + var_attr->flags.attribute = 1; + explicit_attr_list = LISTcreate(); + LISTadd_last(explicit_attr_list, var_attr); + + LISTadd_last(ent->u.entity->attributes, explicit_attr_list); + DICTdefine(ent->symbol_table, attr_id->name, var_attr, &var_attr->name->symbol, OBJ_VARIABLE); + + op1 = EXPcreate_from_symbol(Type_Identifier, e_type_id); + op2 = EXPcreate_from_symbol(Type_Attribute, attr_id); + expr = BIN_EXPcreate(OP_DOT, op1, op2); + + /* + * test: entity_ref '.' attribute_id + * expectation: attr_typ + */ + EXP_resolve_fake.custom_fake = EXP_resolve_entity_handler; + ENTITYresolve_attr_ref_fake.custom_fake = ENTITY_resolve_attr_handler; + + chk_typ = EXPresolve_op_dot(expr, scope); + + assert(EXP_resolve_fake.call_count == 1); + assert(expr->e.op1->type == ent->u.entity->type); + assert(chk_typ == attr_typ); + + /* in case of error SIGABRT will be raised (and non-zero returned) */ + + return 0; +} + +struct test_def tests[] = { + {"resolve_select_enum_member", test_resolve_select_enum_member}, + {"resolve_entity_attribute", test_resolve_entity_attribute}, + {NULL} +}; diff --git a/src/express/test/test_express.c b/src/express/test/test_express.c new file mode 100644 index 000000000..8ce3eb5e1 --- /dev/null +++ b/src/express/test/test_express.c @@ -0,0 +1,146 @@ +#include + +#include "express/express.h" + +/* core */ +#include "express/hash.h" +#include "express/linklist.h" + +/* non-core */ +#include "express/resolve.h" +#include "express/schema.h" + +#include "../token_type.h" +#include "../parse_data.h" +#include "expscan.h" + +#include "driver.h" +#include "fff.h" + +/* + * mock globals + */ + +Error ERROR_circular_reference; +Error ERROR_undefined_schema; + +int yylineno; +Express yyexpresult; +Linked_List PARSEnew_schemas; +int print_objects_while_running; +YYSTYPE yylval; +int yyerrstatus; + +/* + * mock functions + */ +typedef void * (*malloc_func_t) (size_t); +typedef void (*free_func_t) (void *); + +DEFINE_FFF_GLOBALS + +FAKE_VOID_FUNC0(RESOLVEinitialize) +FAKE_VOID_FUNC0(SYMBOLinitialize) +FAKE_VOID_FUNC0(SCOPEinitialize) +FAKE_VOID_FUNC0(TYPEinitialize) +FAKE_VOID_FUNC0(VARinitialize) +FAKE_VOID_FUNC0(ENTITYinitialize) +FAKE_VOID_FUNC0(SCHEMAinitialize) +FAKE_VOID_FUNC0(CASE_ITinitialize) +FAKE_VOID_FUNC0(EXPinitialize) +FAKE_VOID_FUNC0(SCANinitialize) +FAKE_VOID_FUNC0(EXPKWinitialize) +FAKE_VOID_FUNC0(RESOLVEcleanup) +FAKE_VOID_FUNC0(TYPEcleanup) +FAKE_VOID_FUNC0(EXPcleanup) +FAKE_VOID_FUNC0(SCANcleanup) +FAKE_VOID_FUNC0(parserInitState) +FAKE_VOID_FUNC(SCAN_lex_init, char *, FILE *) +FAKE_VOID_FUNC(ParseTrace, FILE *, char *) +FAKE_VOID_FUNC(Parse, void *, int, YYSTYPE, parse_data_t) +FAKE_VOID_FUNC(perplexFree, perplex_t) +FAKE_VOID_FUNC(ParseFree, void *, free_func_t) +FAKE_VOID_FUNC(SCHEMAdefine_use, Schema, Rename *) +FAKE_VOID_FUNC(SCHEMAdefine_reference, Schema, Rename *) +FAKE_VOID_FUNC(SCOPEresolve_subsupers, Scope) +FAKE_VOID_FUNC(SCOPEresolve_types, Scope) +FAKE_VOID_FUNC(SCOPEresolve_expressions_statements, Scope) + +FAKE_VALUE_FUNC(void *, ParseAlloc, malloc_func_t) +FAKE_VALUE_FUNC(char *, SCANstrdup, const char *) +FAKE_VALUE_FUNC(perplex_t, perplexFileScanner, FILE *) +FAKE_VALUE_FUNC(int, yylex, perplex_t) + +void setup() { + RESET_FAKE(RESOLVEinitialize); + RESET_FAKE(SYMBOLinitialize); + RESET_FAKE(SCOPEinitialize); + RESET_FAKE(TYPEinitialize); + RESET_FAKE(VARinitialize); + RESET_FAKE(ENTITYinitialize); + RESET_FAKE(SCHEMAinitialize); + RESET_FAKE(CASE_ITinitialize); + RESET_FAKE(EXPinitialize); + RESET_FAKE(SCANinitialize); + RESET_FAKE(EXPKWinitialize); + RESET_FAKE(RESOLVEcleanup); + RESET_FAKE(TYPEcleanup); + RESET_FAKE(EXPcleanup); + RESET_FAKE(SCANcleanup); + RESET_FAKE(parserInitState); + RESET_FAKE(SCAN_lex_init); + RESET_FAKE(ParseTrace); + RESET_FAKE(Parse); + RESET_FAKE(perplexFree); + RESET_FAKE(ParseFree); + RESET_FAKE(SCHEMAdefine_use); + RESET_FAKE(SCHEMAdefine_reference); + RESET_FAKE(SCOPEresolve_subsupers); + RESET_FAKE(SCOPEresolve_types); + RESET_FAKE(SCOPEresolve_expressions_statements); + RESET_FAKE(ParseAlloc); + RESET_FAKE(SCANstrdup); + RESET_FAKE(perplexFileScanner); + RESET_FAKE(yylex); +} + +int test_express_rename_resolve() { + Schema cur_schema, ref_schema; + Rename *use_ref; + Entity ent; + Symbol *cur_schema_id, *ent_id, *ent_ref, *ref_schema_id; + + cur_schema_id = SYMBOLcreate("cur_schema", 1, "cur.exp"); + ent_id = SYMBOLcreate("line", 1, "cur.exp"); + ent_ref = SYMBOLcreate("line", 1, "ref.exp"); + ref_schema_id = SYMBOLcreate("ref_schema", 1, "ref.exp"); + + cur_schema = SCHEMAcreate(); + cur_schema->symbol = *cur_schema_id; + cur_schema->u.schema->uselist = LISTcreate(); + + ref_schema = SCHEMAcreate(); + ref_schema->symbol = *ref_schema_id; + + ent = ENTITYcreate(ent_id); + DICTdefine(ref_schema->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY); + + /* TODO: create RENcreate(...), refactor SCHEMAadd_use() */ + use_ref = REN_new(); + use_ref->schema_sym = ref_schema_id; + use_ref->old = ent_ref; + use_ref->nnew = ent_ref; + use_ref->rename_type = use; + LISTadd_last(cur_schema->u.schema->uselist, use_ref); + use_ref->schema = ref_schema; + + RENAMEresolve(use_ref, cur_schema); + + assert(use_ref->type == OBJ_ENTITY); + return 0; +} + +struct test_def tests[] = { + {"express_rename_resolve", test_express_rename_resolve}, + {NULL} +}; diff --git a/src/express/test/test_resolve.c b/src/express/test/test_resolve.c new file mode 100644 index 000000000..2fc30ac68 --- /dev/null +++ b/src/express/test/test_resolve.c @@ -0,0 +1,314 @@ +#include + +#include "express/resolve.h" + +/* core */ +#include "express/hash.h" +#include "express/linklist.h" + +/* non-core */ +#include "express/symbol.h" +#include "express/schema.h" +#include "express/expr.h" +#include "express/type.h" + +#include "driver.h" +#include "fff.h" + +/* + * mock globals + */ + +char * EXPRESSprogram_name; +int yylineno; +int __SCOPE_search_id; +int EXPRESSpass; +struct Scope_ * FUNC_NVL; +struct Scope_ * FUNC_USEDIN; + +struct EXPop_entry EXPop_table[OP_LAST]; + +int tag_count; + +/* + * mock functions + */ + +DEFINE_FFF_GLOBALS + +FAKE_VALUE_FUNC(void *, SCOPEfind, Scope, char *, int) +FAKE_VALUE_FUNC(Variable, VARfind, Scope, char *, int) +FAKE_VALUE_FUNC(char *, VARget_simple_name, Variable) +FAKE_VALUE_FUNC(struct Scope_ *, ENTITYfind_inherited_entity, struct Scope_ *, char *, int) +FAKE_VALUE_FUNC(Variable, ENTITYget_named_attribute, Entity, char *) +FAKE_VALUE_FUNC(Variable, ENTITYresolve_attr_ref, Entity, Symbol *, Symbol *) +FAKE_VALUE_FUNC(int, ENTITYdeclares_variable, Entity, Variable) +FAKE_VALUE_FUNC(int, EXPRESS_fail, Express) + +void setup() { + RESOLVEinitialize(); + + RESET_FAKE(SCOPEfind); + RESET_FAKE(VARfind); + RESET_FAKE(VARget_simple_name); + RESET_FAKE(ENTITYfind_inherited_entity); + RESET_FAKE(ENTITYresolve_attr_ref); + RESET_FAKE(ENTITYget_named_attribute); + RESET_FAKE(ENTITYdeclares_variable); + RESET_FAKE(EXPRESS_fail); +} + +void * SCOPEfind_handler(Scope scope, char * name, int type) { + (void) type; + return DICTlookup(scope->symbol_table, name); +} + +int test_exp_resolve_bad_func_call() { + Schema scope; + Symbol *func_id; + Expression func_call; + + scope = SCHEMAcreate(); + + func_id = SYMBOLcreate("func1", 1, "test1"); + func_call = EXPcreate_from_symbol(Type_Funcall, func_id); + + SCOPEfind_fake.custom_fake = SCOPEfind_handler; + + EXP_resolve(func_call, scope, Type_Dont_Care); + + assert(func_call->symbol.resolved != RESOLVED); + + return 0; +} + +int test_exp_resolve_func_call() { + Schema scope; + Symbol *func_id; + Expression func_call; + Function func_def; + + scope = SCHEMAcreate(); + + func_id = SYMBOLcreate("func1", 1, "test1"); + func_call = EXPcreate_from_symbol(Type_Funcall, func_id); + + func_def = TYPEcreate_nostab(func_id, scope, OBJ_FUNCTION); + SCOPEfind_fake.custom_fake = SCOPEfind_handler; + + EXP_resolve(func_call, scope, Type_Dont_Care); + + assert(func_call->symbol.resolved == RESOLVED); + assert(func_call->u.funcall.function == func_def); + + return 0; +} + +Variable VARfind_handler(Scope scope, char *name, int strict) { + (void) strict; + return DICTlookup(scope->symbol_table, name); +} + +int test_exp_resolve_local_identifier() { + Schema scope; + Entity ent; + Expression ent_attr, ent_attr_ref; + Symbol *attr_id, *attr_ref, *ent_id; + Variable v_attr; + Type attr_typ; + + scope = SCHEMAcreate(); + + ent_id = SYMBOLcreate("entity1", 1, "test_2"); + ent = ENTITYcreate(ent_id); + DICT_define(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY); + + attr_id = SYMBOLcreate("attr1", 1, "test_2"); + ent_attr = EXPcreate_from_symbol(Type_Attribute, attr_id); + attr_typ = TYPEcreate(real_); + v_attr = VARcreate(ent_attr, attr_typ); + v_attr->flags.attribute = true; + DICT_define(ent->symbol_table, attr_id->name, v_attr, attr_id, OBJ_VARIABLE); + + attr_ref = SYMBOLcreate("attr1", 1, "test_2"); + ent_attr_ref = EXPcreate_from_symbol(Type_Identifier, attr_ref); + + VARfind_fake.custom_fake = VARfind_handler; + + EXP_resolve(ent_attr_ref, ent, Type_Dont_Care); + + assert(ent_attr_ref->u.variable == v_attr); + assert(ent_attr_ref->symbol.resolved == RESOLVED); + + return 0; +} + +int test_entity_resolve_subtype_expr_entity() { + Schema scope; + Entity ent1, ent2; + Expression subtype_exp; + Symbol *ent1_id, *ent2_id, *ent2_ref; + int chk; + + scope = SCHEMAcreate(); + ent1_id = SYMBOLcreate("ent1", 1, "test_3"); + ent2_id = SYMBOLcreate("ent2", 1, "test_3"); + ent2_ref = SYMBOLcreate("ent2", 1, "test_3"); + ent1 = ENTITYcreate(ent1_id); + ent2 = ENTITYcreate(ent2_id); + + DICTdefine(scope->symbol_table, ent1_id->name, ent1, ent1_id, OBJ_ENTITY); + DICTdefine(scope->symbol_table, ent2_id->name, ent2, ent2_id, OBJ_ENTITY); + + subtype_exp = EXPcreate_from_symbol(Type_Identifier, ent2_ref); + ent1->superscope = scope; + ent1->u.entity->subtypes = LISTcreate(); + ent1->u.entity->subtype_expression = subtype_exp; + + SCOPEfind_fake.custom_fake = SCOPEfind_handler; + chk = ENTITYresolve_subtype_expression(subtype_exp, ent1, &ent1->u.entity->subtypes); + + assert(chk == RESOLVED); + + return 0; +} + +int test_type_resolve_entity() { + Schema scope; + Type sel, ent_base; + Entity ent; + Symbol *ent_id, *sel_id; + + scope = SCHEMAcreate(); + ent_id = SYMBOLcreate("ent", 1, "test_4"); + sel_id = SYMBOLcreate("sel_typ", 1, "test_4"); + + ent_base = TYPEcreate_name(ent_id); + ent_base->superscope = scope; + ent = ENTITYcreate(ent_id); + ent->superscope = scope; + sel = TYPEcreate(select_); + sel->symbol = *sel_id; + sel->u.type->body->list = LISTcreate(); + sel->superscope = scope; + LISTadd_last(sel->u.type->body->list, ent_base); + + DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY); + DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE); + + SCOPEfind_fake.custom_fake = SCOPEfind_handler; + + TYPE_resolve(&sel); + + assert(sel->symbol.resolved == RESOLVED); + + return 0; +} + +int test_stmt_resolve_pcall_proc() { + Schema scope; + Function f; + Procedure p; + Statement s; + Symbol *func_id, *proc_id, *proc_ref; + + scope = SCHEMAcreate(); + + func_id = SYMBOLcreate("func1", 1, "test_5"); + proc_id = SYMBOLcreate("proc1", 1, "test_5"); + proc_ref = SYMBOLcreate("proc1", 1, "test_5"); + + f = ALGcreate(OBJ_FUNCTION); + DICTdefine(scope->symbol_table, func_id->name, f, func_id, OBJ_FUNCTION); + + p = ALGcreate(OBJ_PROCEDURE); + DICTdefine(f->symbol_table, proc_id->name, p, proc_id, OBJ_PROCEDURE); + + s = PCALLcreate(NULL); + s->symbol = *proc_ref; + + SCOPEfind_fake.custom_fake = SCOPEfind_handler; + + STMTresolve(s, f); + + assert(s->u.proc->procedure == p); + + return 0; +} + +int test_scope_resolve_named_types() { + Schema scope; + Type sel, ent_base; + Entity ent; + Symbol *ent_id, *sel_id; + + scope = SCHEMAcreate(); + sel_id = SYMBOLcreate("sel_typ", 1, "test_4"); + ent_id = SYMBOLcreate("ent", 1, "test_4"); + + ent_base = TYPEcreate(entity_); + ent_base->symbol = *ent_id; + ent_base->superscope = scope; + ent = ENTITYcreate(ent_id); + ent->superscope = scope; + sel = TYPEcreate(select_); + sel->symbol = *sel_id; + sel->u.type->body->list = LISTcreate(); + sel->superscope = scope; + LISTadd_last(sel->u.type->body->list, ent_base); + + DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY); + DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE); + + SCOPEfind_fake.custom_fake = SCOPEfind_handler; + + SCOPEresolve_types(scope); + + assert(!(ent->symbol.resolved & RESOLVE_FAILED)); + assert(!(sel->symbol.resolved & RESOLVE_FAILED)); + assert(!(scope->symbol.resolved & RESOLVE_FAILED)); + + return 0; +} + +int test_entity_resolve_supertypes() { + Schema scope; + Entity ent1, ent2; + Symbol *ent1_id, *ent2_id, *ent1_ref; + + scope = SCHEMAcreate(); + ent1_id = SYMBOLcreate("ent1", 1, "test_3"); + ent2_id = SYMBOLcreate("ent2", 1, "test_3"); + ent1_ref = SYMBOLcreate("ent1", 1, "test_3"); + ent1 = ENTITYcreate(ent1_id); + ent2 = ENTITYcreate(ent2_id); + ent1->superscope = scope; + ent2->superscope = scope; + + DICTdefine(scope->symbol_table, ent1_id->name, ent1, ent1_id, OBJ_ENTITY); + DICTdefine(scope->symbol_table, ent2_id->name, ent2, ent2_id, OBJ_ENTITY); + + ent2->u.entity->supertype_symbols = LISTcreate(); + LISTadd_last(ent2->u.entity->supertype_symbols, ent1_ref); + + SCOPEfind_fake.custom_fake = SCOPEfind_handler; + + ENTITYresolve_supertypes(ent2); + + assert(!(ent2->symbol.resolved & RESOLVE_FAILED)); + + return 0; +} + +struct test_def tests[] = { + {"exp_resolve_bad_func_call", test_exp_resolve_bad_func_call}, + {"exp_resolve_func_call", test_exp_resolve_func_call}, + {"exp_resolve_local_identifier", test_exp_resolve_local_identifier}, + {"entity_resolve_subtype_expr_entity", test_entity_resolve_subtype_expr_entity}, + {"type_resolve_entity", test_type_resolve_entity}, + {"stmt_resolve_pcall_proc", test_stmt_resolve_pcall_proc}, + {"scope_resolve_named_types", test_scope_resolve_named_types}, + {"entity_resolve_supertypes_entity", test_entity_resolve_supertypes}, + {NULL} +}; + diff --git a/src/express/test/test_resolve2.c b/src/express/test/test_resolve2.c new file mode 100644 index 000000000..a293dce69 --- /dev/null +++ b/src/express/test/test_resolve2.c @@ -0,0 +1,122 @@ + +#include + +#include "express/resolve.h" + +/* core */ +#include "express/hash.h" +#include "express/linklist.h" + +/* non-core */ +#include "express/type.h" + +#include "driver.h" +#include "fff.h" + +/* + * mock globals + */ + +char * EXPRESSprogram_name; +int EXPRESSpass; +int yylineno; +int print_objects_while_running; + +/* + * mock functions + */ + +DEFINE_FFF_GLOBALS + +FAKE_VOID_FUNC(ENTITYresolve_supertypes, Entity) +FAKE_VOID_FUNC(ENTITYresolve_subtypes, Schema) +FAKE_VOID_FUNC(TYPE_resolve, Type *) +FAKE_VOID_FUNC(TYPEresolve_expressions, Type, Scope) +FAKE_VOID_FUNC(EXP_resolve, Expression, Scope, Type) +FAKE_VOID_FUNC(STMTlist_resolve, Linked_List, Scope) +FAKE_VOID_FUNC(ENTITYresolve_expressions, Entity) + +FAKE_VALUE_FUNC(int, WHEREresolve, Linked_List, Scope, int) +FAKE_VALUE_FUNC(int, EXPRESS_fail, Express) + +void setup() { + RESET_FAKE(ENTITYresolve_supertypes); + RESET_FAKE(ENTITYresolve_subtypes); + RESET_FAKE(TYPE_resolve); + RESET_FAKE(TYPEresolve_expressions); + RESET_FAKE(EXP_resolve); + RESET_FAKE(STMTlist_resolve); + RESET_FAKE(ENTITYresolve_expressions); + RESET_FAKE(WHEREresolve); + RESET_FAKE(EXPRESS_fail); +} + +int test_scope_resolve_expr_stmt() { + Schema scope; + Type sel, ent_base; + Entity ent; + Symbol *ent_id, *sel_id; + + scope = SCHEMAcreate(); + ent_id = SYMBOLcreate("ent", 1, "test_4"); + sel_id = SYMBOLcreate("sel_typ", 1, "test_4"); + + ent_base = TYPEcreate_name(ent_id); + ent_base->superscope = scope; + ent = ENTITYcreate(ent_id); + ent->superscope = scope; + sel = TYPEcreate(select_); + sel->symbol = *sel_id; + sel->u.type->body->list = LISTcreate(); + sel->superscope = scope; + LISTadd_last(sel->u.type->body->list, ent_base); + + DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY); + DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE); + + SCOPEresolve_expressions_statements(scope); + + assert(ENTITYresolve_expressions_fake.call_count == 1); + assert(TYPEresolve_expressions_fake.call_count == 1); + + return 0; +} + +int test_scope_resolve_subsupers() { + Schema scope; + Type sel, ent_base; + Entity ent; + Symbol *ent_id, *sel_id; + + scope = SCHEMAcreate(); + ent_id = SYMBOLcreate("ent", 1, "test_4"); + sel_id = SYMBOLcreate("sel_typ", 1, "test_4"); + + ent_base = TYPEcreate_name(ent_id); + ent_base->superscope = scope; + ent = ENTITYcreate(ent_id); + ent->superscope = scope; + sel = TYPEcreate(select_); + sel->symbol = *sel_id; + sel->u.type->body->list = LISTcreate(); + sel->superscope = scope; + LISTadd_last(sel->u.type->body->list, ent_base); + + DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY); + DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE); + + SCOPEresolve_subsupers(scope); + + assert(TYPE_resolve_fake.call_count == 1); + assert(ENTITYresolve_supertypes_fake.call_count == 1); + assert(ENTITYresolve_subtypes_fake.call_count == 1); + + return 0; +} + + +struct test_def tests[] = { + {"scope_resolve_expr_stmt", test_scope_resolve_expr_stmt}, + {"scope_resolve_subsupers", test_scope_resolve_subsupers}, + {NULL} +}; diff --git a/src/express/test/test_schema.c b/src/express/test/test_schema.c new file mode 100644 index 000000000..80fe0eadc --- /dev/null +++ b/src/express/test/test_schema.c @@ -0,0 +1,201 @@ +#include + +#include "express/schema.h" + +/* core */ +#include "express/hash.h" +#include "express/linklist.h" + + +/* non-core */ +#include "express/variable.h" +#include "express/scope.h" + +#include "driver.h" +#include "fff.h" + +/* + * mock globals + */ +char * EXPRESSprogram_name; +int yylineno; + +int ENTITY_MARK; + + +/* + * mock functions + */ + +DEFINE_FFF_GLOBALS + +FAKE_VALUE_FUNC(int, EXPRESS_fail, Express) +FAKE_VOID_FUNC(SCOPE_get_entities, Scope, Linked_List) +FAKE_VALUE_FUNC(Variable, ENTITYfind_inherited_attribute, struct Scope_ *, char *, struct Symbol_ **) + +void setup() { + RESET_FAKE(EXPRESS_fail) + RESET_FAKE(SCOPE_get_entities) + RESET_FAKE(ENTITYfind_inherited_attribute) +} + +int test_schema_define_ref() { + Schema cur_schema, ref_schema; + Rename *ref_rename; + Symbol *cur_schema_id, *ent_ref, *ref_schema_id; + + cur_schema_id = SYMBOLcreate("cur_schema", 1, "cur.exp"); + ent_ref = SYMBOLcreate("line", 1, "ref.exp"); + ref_schema_id = SYMBOLcreate("ref_schema", 1, "ref.exp"); + + cur_schema = SCHEMAcreate(); + cur_schema->symbol = *cur_schema_id; + cur_schema->u.schema->refdict = DICTcreate(20); + + ref_schema = SCHEMAcreate(); + ref_schema->symbol = *ref_schema_id; + + ref_rename = REN_new(); + ref_rename->schema_sym = ref_schema_id; + ref_rename->old = ent_ref; + ref_rename->nnew = ent_ref; + ref_rename->rename_type = ref; + ref_rename->schema = ref_schema; + DICTdefine(cur_schema->u.schema->refdict, ent_ref->name, ref_rename, ent_ref, OBJ_RENAME); + + SCHEMAdefine_reference(cur_schema, ref_rename); + + assert(cur_schema->u.schema->refdict->KeyCount == 1); + + return 0; +} + +int test_schema_define_use() { + Schema cur_schema, ref_schema; + Rename *use_rename; + Symbol *cur_schema_id, *ent_ref, *ref_schema_id; + + cur_schema_id = SYMBOLcreate("cur_schema", 1, "cur.exp"); + ent_ref = SYMBOLcreate("line", 1, "ref.exp"); + ref_schema_id = SYMBOLcreate("ref_schema", 1, "ref.exp"); + + cur_schema = SCHEMAcreate(); + cur_schema->symbol = *cur_schema_id; + cur_schema->u.schema->usedict = DICTcreate(20); + + ref_schema = SCHEMAcreate(); + ref_schema->symbol = *ref_schema_id; + + use_rename = REN_new(); + use_rename->schema_sym = ref_schema_id; + use_rename->old = ent_ref; + use_rename->nnew = ent_ref; + use_rename->rename_type = use; + use_rename->schema = ref_schema; + DICTdefine(cur_schema->u.schema->usedict, ent_ref->name, use_rename, ent_ref, OBJ_RENAME); + + SCHEMAdefine_use(cur_schema, use_rename); + + assert(cur_schema->u.schema->usedict->KeyCount == 1); + + return 0; +} + +/* TODO: + * currently this function expects OBJ_RENAME stored as OBJ_ENTITY + * (to indicate partial reference) + */ +int test_schema_get_entities_ref() { + Schema cur_schema, ref_schema; + Rename *ref_rename; + Entity ent; + Symbol *cur_schema_id, *ent_id, *ent_ref, *ref_schema_id; + Linked_List r; + + cur_schema_id = SYMBOLcreate("cur_schema", 1, "cur.exp"); + ent_id = SYMBOLcreate("line", 1, "cur.exp"); + ent_ref = SYMBOLcreate("line", 1, "ref.exp"); + ref_schema_id = SYMBOLcreate("ref_schema", 1, "ref.exp"); + + cur_schema = SCHEMAcreate(); + cur_schema->symbol = *cur_schema_id; + cur_schema->u.schema->refdict = DICTcreate(20); + + ref_schema = SCHEMAcreate(); + ref_schema->symbol = *ref_schema_id; + + ent = ENTITYcreate(ent_id); + DICTdefine(ref_schema->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY); + + ref_rename = REN_new(); + ref_rename->schema_sym = ref_schema_id; + ref_rename->old = ent_ref; + ref_rename->nnew = ent_ref; + ref_rename->rename_type = ref; + ref_rename->schema = ref_schema; + ref_rename->object = ent; + DICTdefine(cur_schema->u.schema->refdict, ent_ref->name, ref_rename, ent_ref, OBJ_ENTITY); + + r = LISTcreate(); + cur_schema->search_id = -1; + SCHEMA_get_entities_ref(cur_schema, r); + + assert(LISTget_length(r) == 1); + + return 0; +} + +Variable +ENTITY_find_attr_handler(struct Scope_ *entity, char * name, struct Symbol_** down_sym) +{ + Variable r; + (void) down_sym; + r = DICTlookup(entity->symbol_table, name); + return r; +} + +int test_var_find() { + Schema scope; + Symbol *e_type_id, *attr_id; + Entity ent; + Type attr_typ; + TypeBody tb; + Expression exp_attr; + Variable var_attr, var_ref; + Linked_List explicit_attr_list; + + scope = SCHEMAcreate(); + + e_type_id = SYMBOLcreate("entity1", 1, "test2"); + ent = ENTITYcreate(e_type_id); + DICT_define(scope->symbol_table, e_type_id->name, ent, &ent->symbol, OBJ_ENTITY); + + attr_id = SYMBOLcreate("attr1", 1, "test2"); + exp_attr = EXPcreate_from_symbol(Type_Attribute, attr_id); + tb = TYPEBODYcreate(number_); + attr_typ = TYPEcreate_from_body_anonymously(tb); + attr_typ->superscope = ent; + var_attr = VARcreate(exp_attr, attr_typ); + var_attr->flags.attribute = 1; + explicit_attr_list = LISTcreate(); + LISTadd_last(explicit_attr_list, var_attr); + + LISTadd_last(ent->u.entity->attributes, explicit_attr_list); + DICTdefine(ent->symbol_table, attr_id->name, var_attr, &var_attr->name->symbol, OBJ_VARIABLE); + + ENTITYfind_inherited_attribute_fake.custom_fake = ENTITY_find_attr_handler; + + var_ref = VARfind(ent, "attr1", 1); + + assert(var_ref != NULL); + + return 0; +} + +struct test_def tests[] = { + {"schema_define_ref", test_schema_define_ref}, + {"schema_define_use", test_schema_define_use}, + {"schema_get_entities_ref", test_schema_get_entities_ref}, + {"var_find", test_var_find}, + {NULL} +}; diff --git a/src/express/test/test_scope.c b/src/express/test/test_scope.c new file mode 100644 index 000000000..b59ef4acc --- /dev/null +++ b/src/express/test/test_scope.c @@ -0,0 +1,78 @@ +#include + +#include "express/scope.h" + +/* core */ +#include "express/hash.h" +#include "express/linklist.h" + +/* non-core */ + +#include "driver.h" +#include "fff.h" + +/* + * mock globals + */ + +char * EXPRESSprogram_name; +int yylineno; +int __SCOPE_search_id; + +int ENTITY_MARK; + +Dictionary EXPRESSbuiltins; + + +/* + * mock functions + */ + +DEFINE_FFF_GLOBALS + +FAKE_VALUE_FUNC(int, EXPRESS_fail, Express) + + +void setup() { + RESET_FAKE(EXPRESS_fail); +} + +int test_scope_find() { + Schema scope; + Type sel, ent_base, chk_sel; + Entity ent, chk_ent; + Symbol *ent_id, *sel_id; + + scope = SCHEMAcreate(); + ent_id = SYMBOLcreate("ent", 1, "test_4"); + sel_id = SYMBOLcreate("sel_typ", 1, "test_4"); + + ent_base = TYPEcreate_name(ent_id); + ent_base->superscope = scope; + ent = ENTITYcreate(ent_id); + ent->superscope = scope; + sel = TYPEcreate(select_); + sel->symbol = *sel_id; + sel->u.type->body->list = LISTcreate(); + sel->superscope = scope; + LISTadd_last(sel->u.type->body->list, ent_base); + + DICTdefine(scope->symbol_table, ent_id->name, ent, ent_id, OBJ_ENTITY); + DICTdefine(scope->symbol_table, sel_id->name, sel, sel_id, OBJ_TYPE); + + scope->search_id = -1; + chk_sel = SCOPE_find(scope, "sel_typ", SCOPE_FIND_ENTITY | SCOPE_FIND_TYPE); + + scope->search_id = -1; + chk_ent = SCOPE_find(scope, "ent", SCOPE_FIND_ENTITY | SCOPE_FIND_TYPE); + + assert(chk_sel == sel); + assert(chk_ent == ent); + + return 0; +} + +struct test_def tests[] = { + {"scope_find", test_scope_find}, + {NULL} +}; diff --git a/src/express/test/test_type.c b/src/express/test/test_type.c new file mode 100644 index 000000000..94b1f8b5a --- /dev/null +++ b/src/express/test/test_type.c @@ -0,0 +1,65 @@ +#include + +#include "express/type.h" + +/* core */ +#include "express/hash.h" +#include "express/linklist.h" + +/* non-core */ + +#include "driver.h" +#include "fff.h" + +/* + * mock globals + */ + +char * EXPRESSprogram_name; +int yylineno; + +int tag_count; + +/* + * mock functions + */ + +DEFINE_FFF_GLOBALS + +FAKE_VALUE_FUNC(int, EXPRESS_fail, Express) + + +void setup() { + RESET_FAKE(EXPRESS_fail) + TYPEinitialize(); +} + +int test_type_create_user_defined_tag() { + Schema scope; + Function f; + Type t, g, chk; + Symbol *func_id, *tag_id; + + scope = SCHEMAcreate(); + + func_id = SYMBOLcreate("func1", 1, "test_5"); + tag_id = SYMBOLcreate("item1", 1, "test_5"); + + f = ALGcreate(OBJ_FUNCTION); + f->symbol = *func_id; + DICTdefine(scope->symbol_table, func_id->name, f, func_id, OBJ_FUNCTION); + + g = TYPEcreate(generic_); + t = TYPEcreate_nostab(tag_id, f, OBJ_TAG); + + chk = TYPEcreate_user_defined_tag(g, f, tag_id); + + assert(chk == t); + + return 0; +} + +struct test_def tests[] = { + {"type_create_user_defined_tag", test_type_create_user_defined_tag}, + {NULL} +}; diff --git a/src/express/type.c b/src/express/type.c index b7a7de599..ffcba5915 100644 --- a/src/express/type.c +++ b/src/express/type.c @@ -123,75 +123,8 @@ This module implements the type abstraction. It is */ #include -#include -#include "express/type.h" - -/* Very commonly-used read-only types */ -/* non-constant versions probably aren't necessary? */ -Type Type_Bad; -Type Type_Unknown; -Type Type_Dont_Care; -Type Type_Runtime; /* indicates that this object can't be */ -/* calculated now but must be deferred */ -/* til (the mythical) runtime */ -Type Type_Binary; -Type Type_Boolean; -Type Type_Enumeration; -Type Type_Expression; -Type Type_Aggregate; -Type Type_Repeat; -Type Type_Integer; -Type Type_Number; -Type Type_Real; -Type Type_String; -Type Type_String_Encoded; -Type Type_Logical; -Type Type_Set; -Type Type_Attribute; -Type Type_Entity; -Type Type_Funcall; -Type Type_Generic; -Type Type_Identifier; -Type Type_Oneof; -Type Type_Query; -Type Type_Self; -Type Type_Set_Of_String; -Type Type_Set_Of_Generic; -Type Type_Bag_Of_Generic; - -struct freelist_head TYPEHEAD_fl; -struct freelist_head TYPEBODY_fl; - -Error ERROR_corrupted_type = ERROR_none; - -static Error ERROR_undefined_tag; -/** - * create a type with no symbol table - */ -Type TYPEcreate_nostab( struct Symbol_ *symbol, Scope scope, char objtype ) { - Type t = SCOPEcreate_nostab( OBJ_TYPE ); - TypeHead th = TYPEHEAD_new(); - - t->u.type = th; - t->symbol = *symbol; - DICTdefine( scope->symbol_table, symbol->name, ( Generic )t, &t->symbol, objtype ); - - return t; -} - -/** - * create a type but this is just a shell, either to be completed later - * such as enumerations (which have a symbol table added later) - * or to be used as a type reference - */ -Type TYPEcreate_name( Symbol * symbol ) { - Scope s = SCOPEcreate_nostab( OBJ_TYPE ); - TypeHead t = TYPEHEAD_new(); - s->u.type = t; - s->symbol = *symbol; - return s; -} +#include "express/type.h" Type TYPEcreate_user_defined_tag( Type base, Scope scope, struct Symbol_ *symbol ) { Type t; @@ -215,7 +148,7 @@ Type TYPEcreate_user_defined_tag( Type base, Scope scope, struct Symbol_ *symbol * then we can only refer to existing tags, so produce an error */ if( tag_count < 0 ) { - ERRORreport_with_symbol( ERROR_undefined_tag, symbol, + ERRORreport_with_symbol( UNDEFINED_TAG, symbol, symbol->name ); return( 0 ); } @@ -232,29 +165,6 @@ Type TYPEcreate_user_defined_tag( Type base, Scope scope, struct Symbol_ *symbol return( t ); } -Type TYPEcreate( enum type_enum type ) { - TypeBody tb = TYPEBODYcreate( type ); - Type t = TYPEcreate_from_body_anonymously( tb ); - return( t ); -} - -Type TYPEcreate_from_body_anonymously( TypeBody tb ) { - Type t = SCOPEcreate_nostab( OBJ_TYPE ); - TypeHead th = TYPEHEAD_new(); - - t->u.type = th; - t->u.type->body = tb; - t->symbol.name = 0; - SYMBOLset( t ); - return t; -} - -TypeBody TYPEBODYcreate( enum type_enum type ) { - TypeBody tb = TYPEBODY_new(); - tb->type = type; - return tb; -} - /** * return true if "type t" inherits from "enum type_enum" * may need to be implemented for more types @@ -309,128 +219,12 @@ return( false ); } #endif -Symbol * TYPE_get_symbol( Generic t ) { - return( &( ( Type )t )->symbol ); -} - - /** Initialize the Type module */ void TYPEinitialize() { - MEMinitialize( &TYPEHEAD_fl, sizeof( struct TypeHead_ ), 500, 100 ); - MEMinitialize( &TYPEBODY_fl, sizeof( struct TypeBody_ ), 200, 100 ); - OBJcreate( OBJ_TYPE, TYPE_get_symbol, "type", OBJ_TYPE_BITS ); - /* OBJcreate(OBJ_TYPE,TYPE_get_symbol,"(headless) type", OBJ_UNFINDABLE_BITS);*/ - OBJcreate( OBJ_TAG, TYPE_get_symbol, "tag", OBJ_TYPE_BITS ); - - /* Very commonly-used read-only types */ - Type_Unknown = TYPEcreate( unknown_ ); - Type_Dont_Care = TYPEcreate( special_ ); - Type_Bad = TYPEcreate( special_ ); - Type_Runtime = TYPEcreate( runtime_ ); - - Type_Enumeration = TYPEcreate( enumeration_ ); - Type_Enumeration->u.type->body->flags.shared = 1; - resolved_all( Type_Enumeration ); - - Type_Expression = TYPEcreate( op_ ); - Type_Expression->u.type->body->flags.shared = 1; - - Type_Aggregate = TYPEcreate( aggregate_ ); - Type_Aggregate->u.type->body->flags.shared = 1; - Type_Aggregate->u.type->body->base = Type_Runtime; - - Type_Integer = TYPEcreate( integer_ ); - Type_Integer->u.type->body->flags.shared = 1; - resolved_all( Type_Integer ); - - Type_Real = TYPEcreate( real_ ); - Type_Real->u.type->body->flags.shared = 1; - resolved_all( Type_Real ); - - Type_Number = TYPEcreate( number_ ); - Type_Number->u.type->body->flags.shared = 1; - resolved_all( Type_Number ); - - Type_String = TYPEcreate( string_ ); - Type_String->u.type->body->flags.shared = 1; - resolved_all( Type_String ); - - Type_String_Encoded = TYPEcreate( string_ ); - Type_String_Encoded->u.type->body->flags.shared = 1; - Type_String_Encoded->u.type->body->flags.encoded = 1; - resolved_all( Type_String ); - - Type_Logical = TYPEcreate( logical_ ); - Type_Logical->u.type->body->flags.shared = 1; - resolved_all( Type_Logical ); - - Type_Binary = TYPEcreate( binary_ ); - Type_Binary->u.type->body->flags.shared = 1; - resolved_all( Type_Binary ); - - Type_Number = TYPEcreate( number_ ); - Type_Number->u.type->body->flags.shared = 1; - resolved_all( Type_Number ); - - Type_Boolean = TYPEcreate( boolean_ ); - Type_Boolean->u.type->body->flags.shared = 1; - resolved_all( Type_Boolean ); - - Type_Generic = TYPEcreate( generic_ ); - Type_Generic->u.type->body->flags.shared = 1; - resolved_all( Type_Generic ); - - Type_Set_Of_String = TYPEcreate( set_ ); - Type_Set_Of_String->u.type->body->flags.shared = 1; - Type_Set_Of_String->u.type->body->base = Type_String; - - Type_Set_Of_Generic = TYPEcreate( set_ ); - Type_Set_Of_Generic->u.type->body->flags.shared = 1; - Type_Set_Of_Generic->u.type->body->base = Type_Generic; - - Type_Bag_Of_Generic = TYPEcreate( bag_ ); - Type_Bag_Of_Generic->u.type->body->flags.shared = 1; - Type_Bag_Of_Generic->u.type->body->base = Type_Generic; - - Type_Attribute = TYPEcreate( attribute_ ); - Type_Attribute->u.type->body->flags.shared = 1; - - Type_Entity = TYPEcreate( entity_ ); - Type_Entity->u.type->body->flags.shared = 1; - - Type_Funcall = TYPEcreate( funcall_ ); - Type_Funcall->u.type->body->flags.shared = 1; - - Type_Generic = TYPEcreate( generic_ ); - Type_Generic->u.type->body->flags.shared = 1; - - Type_Identifier = TYPEcreate( identifier_ ); - Type_Identifier->u.type->body->flags.shared = 1; - - Type_Repeat = TYPEcreate( integer_ ); - Type_Repeat->u.type->body->flags.shared = 1; - Type_Repeat->u.type->body->flags.repeat = 1; - - Type_Oneof = TYPEcreate( oneof_ ); - Type_Oneof->u.type->body->flags.shared = 1; - - Type_Query = TYPEcreate( query_ ); - Type_Query->u.type->body->flags.shared = 1; - - Type_Self = TYPEcreate( self_ ); - Type_Self->u.type->body->flags.shared = 1; - - ERROR_corrupted_type = - ERRORcreate( "Corrupted type in %s", SEVERITY_DUMP ); - - ERROR_undefined_tag = - ERRORcreate( "Undefined type tag %s", SEVERITY_ERROR ); } /** Clean up the Type module */ void TYPEcleanup( void ) { - ERRORdestroy( ERROR_corrupted_type ); - ERRORdestroy( ERROR_undefined_tag ); } /** diff --git a/src/express/variable.c b/src/express/variable.c index c6f982509..b3ec9f88a 100644 --- a/src/express/variable.c +++ b/src/express/variable.c @@ -83,23 +83,14 @@ * */ -#include #include + #include "express/variable.h" #include "express/object.h" char * opcode_print( Op_Code o ); -struct freelist_head VAR_fl; - -Symbol * VAR_get_symbol( Generic v ) { - return( &( ( Variable )v )->name->symbol ); -} - /** Initialize the Variable module. */ void VARinitialize() { - MEMinitialize( &VAR_fl, sizeof( struct Variable_ ), 100, 50 ); - /* OBJcreate(OBJ_VARIABLE,VAR_get_symbol,"variable",OBJ_UNUSED_BITS);*/ - OBJcreate( OBJ_VARIABLE, VAR_get_symbol, "variable", OBJ_VARIABLE_BITS ); } /** VARget_simple_name @@ -122,20 +113,3 @@ extern char * VARget_simple_name( Variable v ) { } return EXPget_name( e ); } - -/** VARcreate -** \param name name of variable to create -** \param type type of new variable -** \return the Variable created -** Create and return a new variable. -** -** \note The reference class of the variable is, by default, -** dynamic. Special flags associated with the variable -** (e.g., optional) are initially false. -*/ -Variable VARcreate( Expression name, Type type ) { - Variable v = VAR_new(); - v->name = name; - v->type = type; - return v; -} diff --git a/src/express/ybreaks.py b/src/express/ybreaks.py new file mode 100755 index 000000000..eaae0bc34 --- /dev/null +++ b/src/express/ybreaks.py @@ -0,0 +1,20 @@ +#!/usr/bin/python3 + +# to use in your gdb session +# pi (enters the interactive python interpreter) +# import gdb +# f = open(r'../../ybreaks.txt') +# ybreaks = [gdb.Breakpoint(x.strip()) for x in f] +# +# note you'll also need to set the gdb source path to include the location of the grammar +# dir ../src/express +# dir ../src/express/generated +# + +import re + +y_line_re = re.compile(r'^#line\s(?P[0-9]+)\s"expparse.y"') + +with open(r'generated/expparse.c') as f, open(r'generated/ybreaks.txt', 'w+') as g: + ybreaks = ['expparse.y:%s' % y_line_re.match(l).group('lineno') for l in f if y_line_re.match(l)] + g.writelines(x + '\n' for x in ybreaks) diff --git a/src/test/p21read/p21read.cc b/src/test/p21read/p21read.cc index f3fc1a3c6..cf96b86dd 100644 --- a/src/test/p21read/p21read.cc +++ b/src/test/p21read/p21read.cc @@ -13,13 +13,12 @@ */ extern void SchemaInit( class Registry & ); -#include "sc_version_string.h" -#include -#include -#include -#include -#include -#include +#include "cleditor/STEPfile.h" +#include "clstepcore/sdai.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/Registry.h" +#include "clutils/errordesc.h" #include #include #include "sc_benchmark.h" @@ -27,7 +26,66 @@ extern void SchemaInit( class Registry & ); # include #endif -#include +char * sc_optarg; // global argument pointer +int sc_optind = 0; // global argv index + +int sc_getopt( int argc, char * argv[], char * optstring ) { + static char * next = NULL; + if( sc_optind == 0 ) { + next = NULL; + } + + sc_optarg = NULL; + + if( next == NULL || *next == '\0' ) { + if( sc_optind == 0 ) { + sc_optind++; + } + + if( sc_optind >= argc || argv[sc_optind][0] != '-' || argv[sc_optind][1] == '\0' ) { + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + if( strcmp( argv[sc_optind], "--" ) == 0 ) { + sc_optind++; + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + next = argv[sc_optind]; + next++; // skip past - + sc_optind++; + } + + char c = *next++; + char * cp = strchr( optstring, c ); + + if( cp == NULL || c == ':' ) { + return '?'; + } + + cp++; + if( *cp == ':' ) { + if( *next != '\0' ) { + sc_optarg = next; + next = NULL; + } else if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + sc_optind++; + } else { + return '?'; + } + } + + return c; +} /** * Compare the schema names from the lib (generated by exp2cxx) and @@ -91,7 +149,7 @@ void checkSchemaName( Registry & reg, STEPfile & sf, bool ignoreErr ) { } void printVersion( const char * exe ) { - std::cout << exe << " build info: " << sc_version << std::endl; + std::cout << exe << " build info: " << SC_VERSION << std::endl; } void printUse( const char * exe ) { diff --git a/src/test/p21read/sc_benchmark.cc b/src/test/p21read/sc_benchmark.cc new file mode 100644 index 000000000..2f00cd5a4 --- /dev/null +++ b/src/test/p21read/sc_benchmark.cc @@ -0,0 +1,149 @@ +/// \file sc_benchmark.cc memory info, timers, etc for benchmarking + +#include "./sc_benchmark.h" + +#ifdef _WIN32 +#include +#include +#else +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +/// mem values in kb, times in ms (granularity may be higher than 1ms) +benchVals getMemAndTime( ) { + benchVals vals; +#ifdef __linux__ + // adapted from http://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-run-time-in-c + std::ifstream stat_stream( "/proc/self/stat", std::ios_base::in ); + + // dummy vars for leading entries in stat that we don't care about + std::string pid, comm, state, ppid, pgrp, session, tty_nr; + std::string tpgid, flags, minflt, cminflt, majflt, cmajflt; + std::string /*utime, stime,*/ cutime, cstime, priority, nice; + std::string O, itrealvalue, starttime; + + // the fields we want + unsigned long utime, stime, vsize; + long rss; + + stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr + >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt + >> utime >> stime >> cutime >> cstime >> priority >> nice + >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest + + long page_size_kb = sysconf( _SC_PAGE_SIZE ) / 1024; // in case x86-64 is configured to use 2MB pages + vals.physMemKB = rss * page_size_kb; + vals.virtMemKB = ( vsize / 1024 ) - vals.physMemKB; + vals.userMilliseconds = ( utime * 1000 ) / sysconf( _SC_CLK_TCK ); + vals.sysMilliseconds = ( stime * 1000 ) / sysconf( _SC_CLK_TCK ); +#elif defined(__APPLE__) + // http://stackoverflow.com/a/1911863/382458 +#elif defined(_WIN32) + // http://stackoverflow.com/a/282220/382458 and http://stackoverflow.com/a/64166/382458 + PROCESS_MEMORY_COUNTERS MemoryCntrs; + FILETIME CreationTime, ExitTime, KernelTime, UserTime; + long page_size_kb = 1024; + ULARGE_INTEGER kTime, uTime; + + if( GetProcessMemoryInfo( GetCurrentProcess(), &MemoryCntrs, sizeof( MemoryCntrs ) ) ) { + vals.physMemKB = MemoryCntrs.PeakWorkingSetSize / page_size_kb; + vals.virtMemKB = MemoryCntrs.PeakPagefileUsage / page_size_kb; + } else { + vals.physMemKB = 0; + vals.virtMemKB = 0; + } + + if( GetProcessTimes( GetCurrentProcess(), &CreationTime, &ExitTime, &KernelTime, &UserTime ) ) { + assert( sizeof( FILETIME ) == sizeof( ULARGE_INTEGER ) ); + memcpy( &kTime, &KernelTime, sizeof( FILETIME ) ); + memcpy( &uTime, &UserTime, sizeof( FILETIME ) ); + vals.userMilliseconds = ( long )( uTime.QuadPart / 100000L ); + vals.sysMilliseconds = ( long )( kTime.QuadPart / 100000L ); + } else { + vals.userMilliseconds = 0; + vals.sysMilliseconds = 0; + } +#else +#warning Unknown platform! +#endif // __linux__ + return vals; +} + +// --------------------- benchmark class --------------------- + +benchmark::benchmark( std::string description, bool debugMessages, std::ostream & o_stream ): ostr( o_stream ), + descr( description ), debug( debugMessages ), stopped( false ) { + initialVals = getMemAndTime( ); +} + +benchmark::~benchmark() { + if( !stopped ) { + stop( ); + if( debug ) { + ostr << "benchmark::~benchmark(): stop was not called before destructor!" << std::endl; + } + out( ); + } +} + +void benchmark::stop( ) { + if( stopped ) { + std::cerr << "benchmark::stop(): tried to stop a benchmark that was already stopped!" << std::endl; + } else { + laterVals = getMemAndTime( ); + stopped = true; + } +} + +benchVals benchmark::get( ) { + if( !stopped ) { + laterVals = getMemAndTime( ); + } + benchVals delta; + delta.physMemKB = laterVals.physMemKB - initialVals.physMemKB; + delta.virtMemKB = laterVals.virtMemKB - initialVals.virtMemKB; + delta.sysMilliseconds = laterVals.sysMilliseconds - initialVals.sysMilliseconds; + delta.userMilliseconds = laterVals.userMilliseconds - initialVals.userMilliseconds; + + //If vm is negative, the memory had been requested before initialVals was set. Don't count it + if( delta.virtMemKB < 0 ) { + delta.physMemKB -= delta.virtMemKB; + delta.virtMemKB = 0; + } + return delta; +} + +void benchmark::reset( std::string description ) { + descr = description; + reset(); +} +void benchmark::reset( ) { + stopped = false; + initialVals = getMemAndTime(); +} + +std::string benchmark::str( ) { + return str( get( ) ); +} + +void benchmark::out() { + ostr << str( ) << std::endl; +} + +std::string benchmark::str( const benchVals & bv ) { + std::stringstream ss; + ss << descr << " Physical memory: " << bv.physMemKB << "kb; Virtual memory: " << bv.virtMemKB; + ss << "kb; User CPU time: " << bv.userMilliseconds << "ms; System CPU time: " << bv.sysMilliseconds << "ms"; + return ss.str(); +} + diff --git a/src/test/p21read/sc_benchmark.h b/src/test/p21read/sc_benchmark.h new file mode 100644 index 000000000..5b77317c4 --- /dev/null +++ b/src/test/p21read/sc_benchmark.h @@ -0,0 +1,74 @@ +#ifndef SC_BENCHMARK_H +#define SC_BENCHMARK_H +/// \file sc_benchmark.h memory info, timers, etc for benchmarking + +#ifdef __cplusplus +#include +#include +#include + +extern "C" { +#endif + + typedef struct { + long virtMemKB, physMemKB, userMilliseconds, sysMilliseconds; + } benchVals; + + /** return a benchVals struct with four current statistics for this process: + * virtual and physical memory use in kb, + * user and system cpu time in ms + * + * not yet implemented for OSX or Windows. + */ + benchVals getMemAndTime( ); + +#ifdef __cplusplus +} + + +/** reports the difference in memory and cpu use between when the + * constructor is called and when stop() or the destructor is called. + * + * if the destructor is called and stop() had not previously been + * called, the results are printed to the ostream given in the + * constructor, prefixed by the description. + * + * depends on getMemAndTime() above - may not work on all platforms. + */ + +class benchmark { + protected: + benchVals initialVals, laterVals; +#ifdef _MSC_VER +#pragma warning( push ) +#pragma warning( disable: 4251 ) +#endif + std::ostream & ostr; + std::string descr; +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + bool debug, stopped; + public: + benchmark( std::string description = "", bool debugMessages = true, std::ostream & o_stream = std::cout ); + + /// if 'stopped' is false, uses str(true) to print to ostream + ~benchmark( ); + void reset( ); + void reset( std::string description ); + benchVals get( ); + void stop( ); + + /// converts data member 'laterVals' into a string and returns it + std::string str( ); + + /// outputs result of str() on ostream 'ostr' + void out( ); + + /// converts 'bv' into a string, prefixed by data member 'descr' + std::string str( const benchVals & bv ); +}; + + +#endif //__cplusplus +#endif //SC_BENCHMARK_H diff --git a/src/test/scl2html/scl2html.cc b/src/test/scl2html/scl2html.cc index b981fedae..afe65b11f 100644 --- a/src/test/scl2html/scl2html.cc +++ b/src/test/scl2html/scl2html.cc @@ -35,7 +35,7 @@ #include "../SEarritr.h" // PrintAttrTypeWithAnchor() -// Given an atribute, print out its immediate type (not fundamental). +// Given an attribute, print out its immediate type (not fundamental). // Ah, but if life were so simple. If this attribute is _not_ of a // fundamental type, put in an anchor to somewhere with info on the type. // This could be either the index page Type list, or an entity's page if @@ -49,7 +49,7 @@ void PrintAttrTypeWithAnchor( const TypeDescriptor * typeDesc, ofstream & outhtml ) { std::string buf; - // The type. See src/clstepcore/baseType.h for info + // The type. See clstepcore/baseType.h for info PrimitiveType base = typeDesc->Type(); // the type descriptor for the "referent type," if any. @@ -135,7 +135,7 @@ int PrintAttrsHTML( const EntityDescriptor * ent, ofstream & outhtml ) { // PrintParentAttrsHTML() // This function, given an entity and its parent, recursively travels up // the inheritance tree of the entity, printing to the HTML file a -// description-list structre showing all ancestors. For each ancestor, +// description-list structure showing all ancestors. For each ancestor, // the attributes are printed using the PrintAttrsHTML() function above. void PrintParentAttrsHTML( const EntityDescriptor * ent, const EntityDescriptor * parent, ofstream & outhtml ) { @@ -162,9 +162,9 @@ void PrintParentAttrsHTML( const EntityDescriptor * ent, grandpaNode = ( EntityDescLinkNode * )grandpaNode->NextNode(); } - // Now print the parent's atributes. This calls PrintAttrsHTML() to + // Now print the parent's attributes. This calls PrintAttrsHTML() to // actually print any existing attributes, but to see if there are - // any, we'll check to see if the head of the atribute descriptor list + // any, we'll check to see if the head of the attribute descriptor list // exists. Conversely, once grabbing the head we could print out // the attributes by following the list (attrNode->NextNode()). const AttrDescriptorList * attrList = &( parent->ExplicitAttr() ); @@ -245,7 +245,7 @@ main() { // These are all pointers we need to wander around the registry // information. We'll want to not only look at the current entity - // and its attributes, but also which entites are super- and subclasses + // and its attributes, but also which entities are super- and subclasses // of the current entity. Here, supers isn't really used beyond checking // for ancestors, but we'll use subs to list subclasses and make links // to them. diff --git a/src/test/tests.h b/src/test/tests.h index 52fcb3a59..0494b55d2 100644 --- a/src/test/tests.h +++ b/src/test/tests.h @@ -16,10 +16,10 @@ #include /* General SCL stuff */ -#include -#include -#include -#include +#include "clstepcore/ExpDict.h" +#include "cleditor/STEPfile.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/sdai.h" /* Stuff more or less specifically for the Example schema */ /* The only program that needs this is tstatic. Since the other programs */ diff --git a/src/test/tstatic/tstatic.cc b/src/test/tstatic/tstatic.cc index 3d84f5581..eb6d6f2c5 100644 --- a/src/test/tstatic/tstatic.cc +++ b/src/test/tstatic/tstatic.cc @@ -25,7 +25,7 @@ int main() { // This test creates a bunch of different entities, puts values in them, // prints the values out, links them to an array of entities, and then - // outputs all the enitities in STEP exchange format. + // outputs all the entities in STEP exchange format. // For specifics on the structure of the entity classes, see // the SdaiEXAMPLE_SCHEMA.h header file. diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 05530cb5b..48d826458 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,8 +13,10 @@ foreach(UNITARY_SCHEMA ${UNITARY_SCHEMAS}) endif( UNITARY_SCHEMA MATCHES "fail_.*" ) endforeach(UNITARY_SCHEMA ${UNITARY_SCHEMAS}) -add_subdirectory(p21) -add_subdirectory(cpp) +if(NOT ${SC_BUILD_EXPRESS_ONLY}) + add_subdirectory(p21) + add_subdirectory(cpp) +endif() # Local Variables: # tab-width: 8 diff --git a/test/cpp/CMakeLists.txt b/test/cpp/CMakeLists.txt index cccf68811..7af916d2c 100644 --- a/test/cpp/CMakeLists.txt +++ b/test/cpp/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.12) #c++ tests diff --git a/test/cpp/schema_specific/CMakeLists.txt b/test/cpp/schema_specific/CMakeLists.txt index 51d9c3172..e1bd06e10 100644 --- a/test/cpp/schema_specific/CMakeLists.txt +++ b/test/cpp/schema_specific/CMakeLists.txt @@ -1,14 +1,18 @@ -cmake_minimum_required(VERSION 2.8) +cmake_minimum_required(VERSION 3.12) #c++ tests that depend on a particular schema include_directories( ${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/clstepcore ) # helper function for add_schema_dependent_test # given an sdai target, set out_path_var to the include dir # added as a workaround for changed behavior in newer cmake # versions (changes somewhere between 2.8 and 3.1) function(get_sdai_incl_dir out_path_var sdai_lib) + if (NOT TARGET sdai_${sdai_lib}) + message("sdai_${sdai_lib} is not a target") + return() + endif (NOT TARGET sdai_${sdai_lib}) if(NOT "${sdai_${sdai_lib}_SOURCE_DIR}" STREQUAL "") set(${out_path_var} "${sdai_${sdai_lib}_SOURCE_DIR}" PARENT_SCOPE) return() @@ -52,9 +56,6 @@ function(add_schema_dependent_test name sdai_lib exe_args ) if(NOT ${ARGV4} STREQUAL "") set_property(TARGET tst_${name} APPEND_STRING PROPERTY COMPILE_FLAGS ${ARGV4} ) endif(NOT ${ARGV4} STREQUAL "") - if(NOT "${ARGV5}" MATCHES "NONE") - DEFINE_DLL_IMPORTS("tst_${name}" "${ARGV5}") - endif(NOT "${ARGV5}" MATCHES "NONE") target_link_libraries(tst_${name} sdai_${sdai_lib} ${ARGV5}) add_test(NAME build_cpp_${name} WORKING_DIRECTORY ${CMAKE_BINARY_DIR} @@ -91,7 +92,7 @@ set_tests_properties( test_aggregate_bound_runtime_FAIL1 PROPERTIES add_schema_dependent_test( "inverse_attr1" "inverse_attr" "${SC_SOURCE_DIR}/test/p21/test_inverse_attr.p21" ) add_schema_dependent_test( "inverse_attr2" "inverse_attr" "${SC_SOURCE_DIR}/test/p21/test_inverse_attr.p21" ) add_schema_dependent_test( "inverse_attr3" "inverse_attr" "${SC_SOURCE_DIR}/test/p21/test_inverse_attr.p21" - "${SC_SOURCE_DIR}/src/cllazyfile;${SC_SOURCE_DIR}/src/base/judy/src" "" "steplazyfile" ) + "${SC_SOURCE_DIR}/src/cllazyfile;${SC_SOURCE_DIR}/src/cllazyfile/judy/src" "" "steplazyfile" ) add_schema_dependent_test( "attribute" "inverse_attr" "${SC_SOURCE_DIR}/test/p21/test_inverse_attr.p21" ) if(HAVE_STD_THREAD) diff --git a/test/cpp/schema_specific/aggregate_bound_runtime.cc b/test/cpp/schema_specific/aggregate_bound_runtime.cc index fe103ab8e..f459697e6 100644 --- a/test/cpp/schema_specific/aggregate_bound_runtime.cc +++ b/test/cpp/schema_specific/aggregate_bound_runtime.cc @@ -1,10 +1,10 @@ -#include -#include -#include -#include -#include -#include +#include "cleditor/STEPfile.h" +#include "clstepcore/sdai.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/Registry.h" +#include "clutils/errordesc.h" #include #include #ifdef HAVE_UNISTD_H diff --git a/test/cpp/schema_specific/attribute.cc b/test/cpp/schema_specific/attribute.cc index cb21f19f6..4fab32933 100644 --- a/test/cpp/schema_specific/attribute.cc +++ b/test/cpp/schema_specific/attribute.cc @@ -2,24 +2,80 @@ * 1-Jul-2012 * Test attribute access; uses a tiny schema similar to a subset of IFC2x3 */ -#include -extern void SchemaInit( class Registry & ); -#include "sc_version_string.h" -#include -#include -#include -#include -#include -#include +#include "config.h" +#include "cleditor/STEPfile.h" +#include "clstepcore/sdai.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/Registry.h" +#include "clutils/errordesc.h" #include #include #ifdef HAVE_UNISTD_H # include #endif -#include #include "schema.h" +char * sc_optarg; // global argument pointer +int sc_optind = 0; // global argv index +int sc_getopt( int argc, char * argv[], char * optstring ) { + static char * next = NULL; + if( sc_optind == 0 ) { + next = NULL; + } + + sc_optarg = NULL; + + if( next == NULL || *next == '\0' ) { + if( sc_optind == 0 ) { + sc_optind++; + } + + if( sc_optind >= argc || argv[sc_optind][0] != '-' || argv[sc_optind][1] == '\0' ) { + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + if( strcmp( argv[sc_optind], "--" ) == 0 ) { + sc_optind++; + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + next = argv[sc_optind]; + next++; // skip past - + sc_optind++; + } + + char c = *next++; + char * cp = strchr( optstring, c ); + + if( cp == NULL || c == ':' ) { + return '?'; + } + + cp++; + if( *cp == ':' ) { + if( *next != '\0' ) { + sc_optarg = next; + next = NULL; + } else if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + sc_optind++; + } else { + return '?'; + } + } + + return c; +} int main( int argc, char * argv[] ) { Registry registry( SchemaInit ); InstMgr instance_list; diff --git a/test/cpp/schema_specific/inverse_attr1.cc b/test/cpp/schema_specific/inverse_attr1.cc index 7054464e4..9f776a37a 100644 --- a/test/cpp/schema_specific/inverse_attr1.cc +++ b/test/cpp/schema_specific/inverse_attr1.cc @@ -3,24 +3,82 @@ ** Test inverse attributes; uses a tiny schema similar to a subset of IFC2x3 ** */ -#include -extern void SchemaInit( class Registry & ); -#include "sc_version_string.h" -#include "SubSuperIterators.h" -#include -#include -#include -#include -#include -#include +#include "config.h" +#include "clstepcore/SubSuperIterators.h" +#include "cleditor/STEPfile.h" +#include "clstepcore/sdai.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/Registry.h" +#include "clutils/errordesc.h" #include #include #ifdef HAVE_UNISTD_H # include #endif -#include #include "schema.h" +char * sc_optarg; // global argument pointer +int sc_optind = 0; // global argv index + +int sc_getopt( int argc, char * argv[], char * optstring ) { + static char * next = NULL; + if( sc_optind == 0 ) { + next = NULL; + } + + sc_optarg = NULL; + + if( next == NULL || *next == '\0' ) { + if( sc_optind == 0 ) { + sc_optind++; + } + + if( sc_optind >= argc || argv[sc_optind][0] != '-' || argv[sc_optind][1] == '\0' ) { + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + if( strcmp( argv[sc_optind], "--" ) == 0 ) { + sc_optind++; + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + next = argv[sc_optind]; + next++; // skip past - + sc_optind++; + } + + char c = *next++; + char * cp = strchr( optstring, c ); + + if( cp == NULL || c == ':' ) { + return '?'; + } + + cp++; + if( *cp == ':' ) { + if( *next != '\0' ) { + sc_optarg = next; + next = NULL; + } else if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + sc_optind++; + } else { + return '?'; + } + } + + return c; +} + ///first way of finding inverse attrs bool findInverseAttrs1( InverseAItr iai, InstMgr & instList ) { const Inverse_attribute * ia; @@ -45,7 +103,7 @@ bool findInverseAttrs1( InverseAItr iai, InstMgr & instList ) { EntityNode * en = ( EntityNode * ) relObj->GetHead(); SdaiObject * obj = ( SdaiObject * ) en->node; cout << "file id " << obj->StepFileId() << "; name " - << instList.GetApplication_instance( obj->StepFileId() - 1 )->getEDesc()->Name() << endl; + << instList.GetApplication_instance( obj->StepFileId() - 1 )->eDesc->Name() << endl; } ent_id = i; } diff --git a/test/cpp/schema_specific/inverse_attr2.cc b/test/cpp/schema_specific/inverse_attr2.cc index c538129b0..cdf8dbbd0 100644 --- a/test/cpp/schema_specific/inverse_attr2.cc +++ b/test/cpp/schema_specific/inverse_attr2.cc @@ -3,23 +3,80 @@ ** Test inverse attributes; uses a tiny schema similar to a subset of IFC2x3 ** */ -#include -extern void SchemaInit( class Registry & ); -#include "sc_version_string.h" -#include -#include -#include -#include -#include -#include +#include "config.h" +#include "cleditor/STEPfile.h" +#include "clstepcore/sdai.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/Registry.h" +#include "clutils/errordesc.h" #include #include #ifdef HAVE_UNISTD_H # include #endif -#include #include "schema.h" +char * sc_optarg; // global argument pointer +int sc_optind = 0; // global argv index + +int sc_getopt( int argc, char * argv[], char * optstring ) { + static char * next = NULL; + if( sc_optind == 0 ) { + next = NULL; + } + + sc_optarg = NULL; + + if( next == NULL || *next == '\0' ) { + if( sc_optind == 0 ) { + sc_optind++; + } + + if( sc_optind >= argc || argv[sc_optind][0] != '-' || argv[sc_optind][1] == '\0' ) { + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + if( strcmp( argv[sc_optind], "--" ) == 0 ) { + sc_optind++; + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + next = argv[sc_optind]; + next++; // skip past - + sc_optind++; + } + + char c = *next++; + char * cp = strchr( optstring, c ); + + if( cp == NULL || c == ':' ) { + return '?'; + } + + cp++; + if( *cp == ':' ) { + if( *next != '\0' ) { + sc_optarg = next; + next = NULL; + } else if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + sc_optind++; + } else { + return '?'; + } + } + + return c; +} ///second way of finding inverse attrs bool findInverseAttrs2( InverseAItr iai, InstMgr & instList, Registry & reg ) { const Inverse_attribute * ia; diff --git a/test/cpp/schema_specific/inverse_attr3.cc b/test/cpp/schema_specific/inverse_attr3.cc index b35f5280d..bb4ce0929 100644 --- a/test/cpp/schema_specific/inverse_attr3.cc +++ b/test/cpp/schema_specific/inverse_attr3.cc @@ -4,15 +4,14 @@ * * This test originally used STEPfile, which didn't work. Fixing STEPfile would have been very difficult, it uses lazyInstMgr now. */ -#include -extern void SchemaInit( class Registry & ); -#include +#include "config.h" +#include "cllazyfile/lazyInstMgr.h" #include -#include -#include -#include -#include -#include +#include "clstepcore/sdai.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/Registry.h" +#include "clutils/errordesc.h" #include #include #include @@ -20,9 +19,70 @@ extern void SchemaInit( class Registry & ); #ifdef HAVE_UNISTD_H # include #endif -#include #include "schema.h" +char * sc_optarg; // global argument pointer +int sc_optind = 0; // global argv index + +int sc_getopt( int argc, char * argv[], char * optstring ) { + static char * next = NULL; + if( sc_optind == 0 ) { + next = NULL; + } + + sc_optarg = NULL; + + if( next == NULL || *next == '\0' ) { + if( sc_optind == 0 ) { + sc_optind++; + } + + if( sc_optind >= argc || argv[sc_optind][0] != '-' || argv[sc_optind][1] == '\0' ) { + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + if( strcmp( argv[sc_optind], "--" ) == 0 ) { + sc_optind++; + sc_optarg = NULL; + if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + } + return EOF; + } + + next = argv[sc_optind]; + next++; // skip past - + sc_optind++; + } + + char c = *next++; + char * cp = strchr( optstring, c ); + + if( cp == NULL || c == ':' ) { + return '?'; + } + + cp++; + if( *cp == ':' ) { + if( *next != '\0' ) { + sc_optarg = next; + next = NULL; + } else if( sc_optind < argc ) { + sc_optarg = argv[sc_optind]; + sc_optind++; + } else { + return '?'; + } + } + + return c; +} + + int main( int argc, char * argv[] ) { int exitStatus = EXIT_SUCCESS; if( argc != 2 ) { diff --git a/test/cpp/schema_specific/stepfile_rw_progress.cc b/test/cpp/schema_specific/stepfile_rw_progress.cc index 3b0aece60..1fe5cb0dc 100644 --- a/test/cpp/schema_specific/stepfile_rw_progress.cc +++ b/test/cpp/schema_specific/stepfile_rw_progress.cc @@ -1,11 +1,10 @@ -#include "sc_version_string.h" -#include -#include -#include -#include -#include -#include +#include "cleditor/STEPfile.h" +#include "clstepcore/sdai.h" +#include "clstepcore/STEPattribute.h" +#include "clstepcore/ExpDict.h" +#include "clstepcore/Registry.h" +#include "clutils/errordesc.h" #include #include @@ -31,7 +30,7 @@ #ifdef HAVE_STD_CHRONO # define DELAY(t) std::this_thread::sleep_for(std::chrono::milliseconds(t)); #else -# ifndef __WIN32__ +# ifndef _WIN32 # define DELAY(t) usleep( t * 100 ) # else # include diff --git a/test/p21/CMakeLists.txt b/test/p21/CMakeLists.txt index b16bdd7b3..7d533f9ca 100644 --- a/test/p21/CMakeLists.txt +++ b/test/p21/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.12) #test part 21 files #necessary macros won't already be defined if SC_BUILD_SCHEMAS is set to ""